Skip to content

Instantly share code, notes, and snippets.

@lambdageek
Created July 25, 2022 23:19
Show Gist options
  • Save lambdageek/e54206e2e5365e3f3440a4942a303721 to your computer and use it in GitHub Desktop.
Save lambdageek/e54206e2e5365e3f3440a4942a303721 to your computer and use it in GitHub Desktop.
//! Licensed to the .NET Foundation under one or more agreements.
//! The .NET Foundation licenses this file to you under the MIT license.
var __dotnet_runtime = (function (exports) {
'use strict';
var ProductVersion = "7.0.0";
var Configuration = "Debug";
var MonoWasmThreads = true;
// Licensed to the .NET Foundation under one or more agreements.
const MonoMethodNull = 0;
const MonoObjectNull = 0;
const MonoArrayNull = 0;
const MonoAssemblyNull = 0;
const MonoClassNull = 0;
const MonoTypeNull = 0;
const MonoStringNull = 0;
const MonoObjectRefNull = 0;
const MonoStringRefNull = 0;
const JSHandleDisposed = -1;
const JSHandleNull = 0;
const GCHandleNull = 0;
const VoidPtrNull = 0;
const CharPtrNull = 0;
const NativePointerNull = 0;
function coerceNull(ptr) {
if ((ptr === null) || (ptr === undefined))
return 0;
else
return ptr;
}
const wasm_type_symbol = Symbol.for("wasm type");
// see src\mono\wasm\runtime\rollup.config.js
// inline this, because the lambda could allocate closure on hot path otherwise
function mono_assert(condition, messageFactory) {
if (!condition) {
const message = typeof messageFactory === "string"
? messageFactory
: messageFactory();
throw new Error(`Assert failed: ${message}`);
}
}
// Evaluates whether a value is nullish (same definition used as the ?? operator,
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Nullish_coalescing_operator)
function is_nullish(value) {
return (value === undefined) || (value === null);
}
/// Always throws. Used to handle unreachable switch branches when TypeScript refines the type of a variable
/// to 'never' after you handle all the cases it knows about.
function assertNever(x) {
throw new Error("Unexpected value: " + x);
}
/// returns true if the given value is not Thenable
///
/// Useful if some function returns a value or a promise of a value.
function notThenable(x) {
return typeof x !== "object" || typeof (x.then) !== "function";
}
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// these are our public API (except internal)
let Module;
let MONO$1;
let BINDING$1;
let INTERNAL$1;
let EXPORTS;
let IMPORTS;
// these are imported and re-exported from emscripten internals
let ENVIRONMENT_IS_ESM;
let ENVIRONMENT_IS_NODE;
let ENVIRONMENT_IS_SHELL;
let ENVIRONMENT_IS_WEB;
let ENVIRONMENT_IS_WORKER;
let ENVIRONMENT_IS_PTHREAD;
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
function set_imports_exports(imports, exports) {
MONO$1 = exports.mono;
BINDING$1 = exports.binding;
INTERNAL$1 = exports.internal;
Module = exports.module;
EXPORTS = exports.marshaled_exports; // [JSExport]
IMPORTS = exports.marshaled_imports; // [JSImport]
ENVIRONMENT_IS_ESM = imports.isESM;
ENVIRONMENT_IS_NODE = imports.isNode;
ENVIRONMENT_IS_SHELL = imports.isShell;
ENVIRONMENT_IS_WEB = imports.isWeb;
ENVIRONMENT_IS_WORKER = imports.isWorker;
ENVIRONMENT_IS_PTHREAD = imports.isPThread;
runtimeHelpers.quit = imports.quit_;
runtimeHelpers.ExitStatus = imports.ExitStatus;
runtimeHelpers.requirePromise = imports.requirePromise;
}
let monoConfig = {};
let runtime_is_ready = false;
const runtimeHelpers = {
namespace: "System.Runtime.InteropServices.JavaScript",
classname: "Runtime",
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) {
runtime_is_ready = value;
INTERNAL$1.mono_wasm_runtime_is_ready = value;
},
get config() {
return monoConfig;
},
set config(value) {
monoConfig = value;
MONO$1.config = value;
Module.config = value;
},
diagnostic_tracing: false,
enable_debugging: false,
fetch: null
};
// Licensed to the .NET Foundation under one or more agreements.
const fn_signatures$1 = [
// MONO
["mono_wasm_register_root", "number", ["number", "number", "string"]],
["mono_wasm_deregister_root", null, ["number"]],
["mono_wasm_string_get_data", null, ["number", "number", "number", "number"]],
["mono_wasm_string_get_data_ref", null, ["number", "number", "number", "number"]],
["mono_wasm_set_is_debugger_attached", "void", ["bool"]],
["mono_wasm_send_dbg_command", "bool", ["number", "number", "number", "number", "number"]],
["mono_wasm_send_dbg_command_with_parms", "bool", ["number", "number", "number", "number", "number", "number", "string"]],
["mono_wasm_setenv", null, ["string", "string"]],
["mono_wasm_parse_runtime_options", null, ["number", "number"]],
["mono_wasm_strdup", "number", ["string"]],
["mono_background_exec", null, []],
["mono_set_timeout_exec", null, []],
["mono_wasm_load_icu_data", "number", ["number"]],
["mono_wasm_get_icudt_name", "string", ["string"]],
["mono_wasm_add_assembly", "number", ["string", "number", "number"]],
["mono_wasm_add_satellite_assembly", "void", ["string", "string", "number", "number"]],
["mono_wasm_load_runtime", null, ["string", "number"]],
["mono_wasm_exit", null, ["number"]],
["mono_wasm_change_debugger_log_level", "void", ["number"]],
// BINDING
["mono_wasm_get_corlib", "number", []],
["mono_wasm_assembly_load", "number", ["string"]],
["mono_wasm_find_corlib_class", "number", ["string", "string"]],
["mono_wasm_assembly_find_class", "number", ["number", "string", "string"]],
["mono_wasm_runtime_run_module_cctor", "void", ["number"]],
["mono_wasm_find_corlib_type", "number", ["string", "string"]],
["mono_wasm_assembly_find_type", "number", ["number", "string", "string"]],
["mono_wasm_assembly_find_method", "number", ["number", "string", "number"]],
["mono_wasm_invoke_method", "number", ["number", "number", "number", "number"]],
["mono_wasm_invoke_method_ref", "void", ["number", "number", "number", "number", "number"]],
["mono_wasm_string_get_utf8", "number", ["number"]],
["mono_wasm_string_from_utf16_ref", "void", ["number", "number", "number"]],
["mono_wasm_get_obj_type", "number", ["number"]],
["mono_wasm_array_length", "number", ["number"]],
["mono_wasm_array_get", "number", ["number", "number"]],
["mono_wasm_array_get_ref", "void", ["number", "number", "number"]],
["mono_wasm_obj_array_new", "number", ["number"]],
["mono_wasm_obj_array_new_ref", "void", ["number", "number"]],
["mono_wasm_obj_array_set", "void", ["number", "number", "number"]],
["mono_wasm_obj_array_set_ref", "void", ["number", "number", "number"]],
["mono_wasm_register_bundled_satellite_assemblies", "void", []],
["mono_wasm_try_unbox_primitive_and_get_type_ref", "number", ["number", "number", "number"]],
["mono_wasm_box_primitive_ref", "void", ["number", "number", "number", "number"]],
["mono_wasm_intern_string_ref", "void", ["number"]],
["mono_wasm_assembly_get_entry_point", "number", ["number"]],
["mono_wasm_get_delegate_invoke_ref", "number", ["number"]],
["mono_wasm_string_array_new_ref", "void", ["number", "number"]],
["mono_wasm_typed_array_new_ref", "void", ["number", "number", "number", "number", "number"]],
["mono_wasm_class_get_type", "number", ["number"]],
["mono_wasm_type_get_class", "number", ["number"]],
["mono_wasm_get_type_name", "string", ["number"]],
["mono_wasm_get_type_aqn", "string", ["number"]],
// MONO.diagnostics
["mono_wasm_event_pipe_enable", "bool", ["string", "number", "number", "string", "bool", "number"]],
["mono_wasm_event_pipe_session_start_streaming", "bool", ["number"]],
["mono_wasm_event_pipe_session_disable", "bool", ["number"]],
["mono_wasm_diagnostic_server_create_thread", "bool", ["string", "number"]],
["mono_wasm_diagnostic_server_thread_attach_to_runtime", "void", []],
["mono_wasm_diagnostic_server_post_resume_runtime", "void", []],
["mono_wasm_diagnostic_server_create_stream", "number", []],
//DOTNET
["mono_wasm_string_from_js", "number", ["string"]],
//INTERNAL
["mono_wasm_exit", "void", ["number"]],
["mono_wasm_set_main_args", "void", ["number", "number"]],
["mono_wasm_enable_on_demand_gc", "void", ["number"]],
["mono_profiler_init_aot", "void", ["number"]],
["mono_wasm_exec_regression", "number", ["number", "string"]],
["mono_wasm_invoke_method_bound", "number", ["number", "number"]],
["mono_wasm_write_managed_pointer_unsafe", "void", ["number", "number"]],
["mono_wasm_copy_managed_pointer", "void", ["number", "number"]],
["mono_wasm_i52_to_f64", "number", ["number", "number"]],
["mono_wasm_u52_to_f64", "number", ["number", "number"]],
["mono_wasm_f64_to_i52", "number", ["number", "number"]],
["mono_wasm_f64_to_u52", "number", ["number", "number"]],
];
const wrapped_c_functions = {};
for (const sig of fn_signatures$1) {
const wf = wrapped_c_functions;
// lazy init on first run
wf[sig[0]] = function (...args) {
const fce = Module.cwrap(sig[0], sig[1], sig[2], sig[3]);
wf[sig[0]] = fce;
return fce(...args);
};
}
function wrap_c_function(name) {
const wf = wrapped_c_functions;
const sig = fn_signatures$1.find(s => s[0] === name);
if (!(sig)) throw new Error(`Assert failed: Function ${name} not found`); // inlined mono_assert
const fce = Module.cwrap(sig[0], sig[1], sig[2], sig[3]);
wf[sig[0]] = fce;
return fce;
}
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
function toBigInt(x) {
return BigInt(x[0]) | BigInt(x[1]) << BigInt(32);
}
function fromBigInt(x) {
if (x < BigInt(0))
throw new Error(`${x} is not a valid 64 bit integer`);
if (x > BigInt(0xFFFFFFFFFFFFFFFF))
throw new Error(`${x} is not a valid 64 bit integer`);
const low = Number(x & BigInt(0xFFFFFFFF));
const high = Number(x >> BigInt(32));
return [low, high];
}
function dangerousToNumber(x) {
return x[0] | x[1] << 32;
}
function fromNumber(x) {
if (x < 0)
throw new Error(`${x} is not a valid 64 bit integer`);
if ((x >> 32) > 0xFFFFFFFF)
throw new Error(`${x} is not a valid 64 bit integer`);
if (Math.trunc(x) != x)
throw new Error(`${x} is not a valid 64 bit integer`);
return [x & 0xFFFFFFFF, x >> 32];
}
function pack32(lo, hi) {
return [lo, hi];
}
function unpack32(x) {
return [x[0], x[1]];
}
const zero = [0, 0];
const alloca_stack = [];
const alloca_buffer_size = 32 * 1024;
let alloca_base, alloca_offset, alloca_limit;
let HEAPI64 = null;
function _ensure_allocated() {
if (alloca_base)
return;
alloca_base = Module._malloc(alloca_buffer_size);
alloca_offset = alloca_base;
alloca_limit = (alloca_base + alloca_buffer_size);
}
const is_bigint_supported = typeof BigInt !== "undefined" && typeof BigInt64Array !== "undefined";
function temp_malloc(size) {
_ensure_allocated();
if (!alloca_stack.length)
throw new Error("No temp frames have been created at this point");
const result = alloca_offset;
alloca_offset += size;
if (alloca_offset >= alloca_limit)
throw new Error("Out of temp storage space");
return result;
}
function _create_temp_frame() {
_ensure_allocated();
alloca_stack.push(alloca_offset);
}
function _release_temp_frame() {
if (!alloca_stack.length)
throw new Error("No temp frames have been created at this point");
alloca_offset = alloca_stack.pop();
}
function assert_int_in_range(value, min, max) {
if (!(Number.isSafeInteger(value))) throw new Error(`Assert failed: Value is not an integer: ${value} (${typeof (value)})`); // inlined mono_assert
if (!(value >= min && value <= max)) throw new Error(`Assert failed: Overflow: value ${value} is out of ${min} ${max} range`); // inlined mono_assert
}
function _zero_region(byteOffset, sizeBytes) {
if (((byteOffset % 4) === 0) && ((sizeBytes % 4) === 0))
Module.HEAP32.fill(0, byteOffset >>> 2, sizeBytes >>> 2);
else
Module.HEAP8.fill(0, byteOffset, sizeBytes);
}
function setB32(offset, value) {
const boolValue = !!value;
if (typeof (value) === "number")
assert_int_in_range(value, 0, 1);
Module.HEAP32[offset >>> 2] = boolValue ? 1 : 0;
}
function setU8(offset, value) {
assert_int_in_range(value, 0, 0xFF);
Module.HEAPU8[offset] = value;
}
function setU16(offset, value) {
assert_int_in_range(value, 0, 0xFFFF);
Module.HEAPU16[offset >>> 1] = value;
}
function setU32_unchecked(offset, value) {
Module.HEAPU32[offset >>> 2] = value;
}
function setU32(offset, value) {
assert_int_in_range(value, 0, 4294967295);
Module.HEAPU32[offset >>> 2] = value;
}
function setI8(offset, value) {
assert_int_in_range(value, -0x80, 0x7F);
Module.HEAP8[offset] = value;
}
function setI16(offset, value) {
assert_int_in_range(value, -0x8000, 0x7FFF);
Module.HEAP16[offset >>> 1] = value;
}
function setI32_unchecked(offset, value) {
Module.HEAP32[offset >>> 2] = value;
}
function setI32(offset, value) {
assert_int_in_range(value, -2147483648, 2147483647);
Module.HEAP32[offset >>> 2] = value;
}
function autoThrowI52(error) {
if (error === 0 /* I52Error.NONE */)
return;
switch (error) {
case 1 /* I52Error.NON_INTEGRAL */:
throw new Error("value was not an integer");
case 2 /* I52Error.OUT_OF_RANGE */:
throw new Error("value out of range");
default:
throw new Error("unknown internal error");
}
}
/**
* Throws for values which are not 52 bit integer. See Number.isSafeInteger()
*/
function setI52(offset, value) {
if (!(Number.isSafeInteger(value))) throw new Error(`Assert failed: Value is not a safe integer: ${value} (${typeof (value)})`); // inlined mono_assert
const error = wrapped_c_functions.mono_wasm_f64_to_i52(offset, value);
autoThrowI52(error);
}
/**
* Throws for values which are not 52 bit integer or are negative. See Number.isSafeInteger().
*/
function setU52(offset, value) {
if (!(Number.isSafeInteger(value))) throw new Error(`Assert failed: Value is not a safe integer: ${value} (${typeof (value)})`); // inlined mono_assert
if (!(value >= 0)) throw new Error("Assert failed: Can't convert negative Number into UInt64"); // inlined mono_assert
const error = wrapped_c_functions.mono_wasm_f64_to_u52(offset, value);
autoThrowI52(error);
}
function setI64Big(offset, value) {
if (!(is_bigint_supported)) throw new Error("Assert failed: BigInt is not supported."); // inlined mono_assert
if (!(typeof value === "bigint")) throw new Error(`Assert failed: Value is not an bigint: ${value} (${typeof (value)})`); // inlined mono_assert
if (!(value >= min_int64_big && value <= max_int64_big)) throw new Error(`Assert failed: Overflow: value ${value} is out of ${min_int64_big} ${max_int64_big} range`); // inlined mono_assert
HEAPI64[offset >>> 3] = value;
}
function setF32(offset, value) {
if (!(typeof value === "number")) throw new Error(`Assert failed: Value is not a Number: ${value} (${typeof (value)})`); // inlined mono_assert
Module.HEAPF32[offset >>> 2] = value;
}
function setF64(offset, value) {
if (!(typeof value === "number")) throw new Error(`Assert failed: Value is not a Number: ${value} (${typeof (value)})`); // inlined mono_assert
Module.HEAPF64[offset >>> 3] = value;
}
function getB32(offset) {
return !!(Module.HEAP32[offset >>> 2]);
}
function getU8(offset) {
return Module.HEAPU8[offset];
}
function getU16(offset) {
return Module.HEAPU16[offset >>> 1];
}
function getU32(offset) {
return Module.HEAPU32[offset >>> 2];
}
function getI8(offset) {
return Module.HEAP8[offset];
}
function getI16(offset) {
return Module.HEAP16[offset >>> 1];
}
function getI32(offset) {
return Module.HEAP32[offset >>> 2];
}
/**
* Throws for Number.MIN_SAFE_INTEGER > value > Number.MAX_SAFE_INTEGER
*/
function getI52(offset) {
const result = wrapped_c_functions.mono_wasm_i52_to_f64(offset, runtimeHelpers._i52_error_scratch_buffer);
const error = getI32(runtimeHelpers._i52_error_scratch_buffer);
autoThrowI52(error);
return result;
}
/**
* Throws for 0 > value > Number.MAX_SAFE_INTEGER
*/
function getU52(offset) {
const result = wrapped_c_functions.mono_wasm_u52_to_f64(offset, runtimeHelpers._i52_error_scratch_buffer);
const error = getI32(runtimeHelpers._i52_error_scratch_buffer);
autoThrowI52(error);
return result;
}
function getI64Big(offset) {
if (!(is_bigint_supported)) throw new Error("Assert failed: BigInt is not supported."); // inlined mono_assert
return HEAPI64[offset >>> 3];
}
function getF32(offset) {
return Module.HEAPF32[offset >>> 2];
}
function getF64(offset) {
return Module.HEAPF64[offset >>> 3];
}
let max_int64_big;
let min_int64_big;
function afterUpdateGlobalBufferAndViews(buffer) {
if (is_bigint_supported) {
max_int64_big = BigInt("9223372036854775807");
min_int64_big = BigInt("-9223372036854775808");
HEAPI64 = new BigInt64Array(buffer);
}
}
function getCU64(offset) {
const lo = getU32(offset);
const hi = getU32(offset + 4);
return pack32(lo, hi);
}
function setCU64(offset, value) {
const [lo, hi] = unpack32(value);
setU32_unchecked(offset, lo);
setU32_unchecked(offset + 4, hi);
}
function withStackAlloc(bytesWanted, f, ud1, ud2, ud3) {
const sp = Module.stackSave();
const ptr = Module.stackAlloc(bytesWanted);
try {
return f(ptr, ud1, ud2, ud3);
}
finally {
Module.stackRestore(sp);
}
}
const BuiltinAtomics = globalThis.Atomics;
const Atomics$1 = MonoWasmThreads ? {
storeI32(offset, value) {
BuiltinAtomics.store(Module.HEAP32, offset >>> 2, value);
},
notifyI32(offset, count) {
BuiltinAtomics.notify(Module.HEAP32, offset >>> 2, count);
}
} : {
storeI32: setI32,
notifyI32: () => { }
};
// Licensed to the .NET Foundation under one or more agreements.
const maxScratchRoots = 8192;
let _scratch_root_buffer = null;
let _scratch_root_free_indices = null;
let _scratch_root_free_indices_count = 0;
const _scratch_root_free_instances = [];
const _external_root_free_instances = [];
/**
* 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.
*/
function mono_wasm_new_root_buffer(capacity, name) {
if (capacity <= 0)
throw new Error("capacity >= 1");
capacity = capacity | 0;
const capacityBytes = capacity * 4;
const offset = Module._malloc(capacityBytes);
if ((offset % 4) !== 0)
throw new Error("Malloc returned an unaligned offset");
_zero_region(offset, capacityBytes);
return new WasmRootBuffer(offset, capacity, true, name);
}
/**
* Creates a root buffer object representing an existing allocation in the native heap and registers
* the allocation with the GC. The caller is responsible for managing the lifetime of the allocation.
*/
function mono_wasm_new_root_buffer_from_pointer(offset, capacity, name) {
if (capacity <= 0)
throw new Error("capacity >= 1");
capacity = capacity | 0;
const capacityBytes = capacity * 4;
if ((offset % 4) !== 0)
throw new Error("Unaligned offset");
_zero_region(offset, capacityBytes);
return new WasmRootBuffer(offset, capacity, false, name);
}
/**
* 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().
*/
function mono_wasm_new_external_root(address) {
let result;
if (!address)
throw new Error("address must be a location in the native heap");
if (_external_root_free_instances.length > 0) {
result = _external_root_free_instances.pop();
result._set_address(address);
}
else {
result = new WasmExternalRoot(address);
}
return result;
}
/**
* 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.
*/
function mono_wasm_new_root(value = undefined) {
let result;
if (_scratch_root_free_instances.length > 0) {
result = _scratch_root_free_instances.pop();
}
else {
const index = _mono_wasm_claim_scratch_index();
const buffer = _scratch_root_buffer;
result = new WasmJsOwnedRoot(buffer, index);
}
if (value !== undefined) {
if (typeof (value) !== "number")
throw new Error("value must be an address in the managed heap");
result.set(value);
}
else {
result.set(0);
}
return result;
}
/**
* Allocates 1 or more temporary roots, accepting either a number of roots or an array of pointers.
* mono_wasm_new_roots(n): returns an array of N zero-initialized roots.
* mono_wasm_new_roots([a, b, ...]) returns an array of new roots initialized with each element.
* Each root must be released with its release method, or using the mono_wasm_release_roots API.
*/
function mono_wasm_new_roots(count_or_values) {
let result;
if (Array.isArray(count_or_values)) {
result = new Array(count_or_values.length);
for (let i = 0; i < result.length; i++)
result[i] = mono_wasm_new_root(count_or_values[i]);
}
else if ((count_or_values | 0) > 0) {
result = new Array(count_or_values);
for (let i = 0; i < result.length; i++)
result[i] = mono_wasm_new_root();
}
else {
throw new Error("count_or_values must be either an array or a number greater than 0");
}
return result;
}
/**
* 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
*/
function mono_wasm_release_roots(...args) {
for (let i = 0; i < args.length; i++) {
if (is_nullish(args[i]))
continue;
args[i].release();
}
}
function _mono_wasm_release_scratch_index(index) {
if (index === undefined)
return;
_scratch_root_buffer.set(index, 0);
_scratch_root_free_indices[_scratch_root_free_indices_count] = index;
_scratch_root_free_indices_count++;
}
function _mono_wasm_claim_scratch_index() {
if (is_nullish(_scratch_root_buffer) || !_scratch_root_free_indices) {
_scratch_root_buffer = mono_wasm_new_root_buffer(maxScratchRoots, "js roots");
_scratch_root_free_indices = new Int32Array(maxScratchRoots);
_scratch_root_free_indices_count = maxScratchRoots;
for (let i = 0; i < maxScratchRoots; i++)
_scratch_root_free_indices[i] = maxScratchRoots - i - 1;
}
if (_scratch_root_free_indices_count < 1)
throw new Error("Out of scratch root space");
const result = _scratch_root_free_indices[_scratch_root_free_indices_count - 1];
_scratch_root_free_indices_count--;
return result;
}
class WasmRootBuffer {
constructor(offset, capacity, ownsAllocation, name) {
const capacityBytes = capacity * 4;
this.__offset = offset;
this.__offset32 = offset >>> 2;
this.__count = capacity;
this.length = capacity;
this.__handle = wrapped_c_functions.mono_wasm_register_root(offset, capacityBytes, name || "noname");
this.__ownsAllocation = ownsAllocation;
}
_throw_index_out_of_range() {
throw new Error("index out of range");
}
_check_in_range(index) {
if ((index >= this.__count) || (index < 0))
this._throw_index_out_of_range();
}
get_address(index) {
this._check_in_range(index);
return this.__offset + (index * 4);
}
get_address_32(index) {
this._check_in_range(index);
return this.__offset32 + index;
}
// NOTE: These functions do not use the helpers from memory.ts because WasmRoot.get and WasmRoot.set
// are hot-spots when you profile any application that uses the bindings extensively.
get(index) {
this._check_in_range(index);
const offset = this.get_address_32(index);
return Module.HEAPU32[offset];
}
set(index, value) {
const address = this.get_address(index);
wrapped_c_functions.mono_wasm_write_managed_pointer_unsafe(address, value);
return value;
}
copy_value_from_address(index, sourceAddress) {
const destinationAddress = this.get_address(index);
wrapped_c_functions.mono_wasm_copy_managed_pointer(destinationAddress, sourceAddress);
}
_unsafe_get(index) {
return Module.HEAPU32[this.__offset32 + index];
}
_unsafe_set(index, value) {
const address = this.__offset + index;
wrapped_c_functions.mono_wasm_write_managed_pointer_unsafe(address, value);
}
clear() {
if (this.__offset)
_zero_region(this.__offset, this.__count * 4);
}
release() {
if (this.__offset && this.__ownsAllocation) {
wrapped_c_functions.mono_wasm_deregister_root(this.__offset);
_zero_region(this.__offset, this.__count * 4);
Module._free(this.__offset);
}
this.__handle = this.__offset = this.__count = this.__offset32 = 0;
}
toString() {
return `[root buffer @${this.get_address(0)}, size ${this.__count} ]`;
}
}
class WasmJsOwnedRoot {
constructor(buffer, index) {
this.__buffer = buffer; //TODO
this.__index = index;
}
get_address() {
return this.__buffer.get_address(this.__index);
}
get_address_32() {
return this.__buffer.get_address_32(this.__index);
}
get address() {
return this.__buffer.get_address(this.__index);
}
get() {
const result = this.__buffer._unsafe_get(this.__index);
return result;
}
set(value) {
const destinationAddress = this.__buffer.get_address(this.__index);
wrapped_c_functions.mono_wasm_write_managed_pointer_unsafe(destinationAddress, value);
return value;
}
copy_from(source) {
const sourceAddress = source.address;
const destinationAddress = this.address;
wrapped_c_functions.mono_wasm_copy_managed_pointer(destinationAddress, sourceAddress);
}
copy_to(destination) {
const sourceAddress = this.address;
const destinationAddress = destination.address;
wrapped_c_functions.mono_wasm_copy_managed_pointer(destinationAddress, sourceAddress);
}
copy_from_address(source) {
const destinationAddress = this.address;
wrapped_c_functions.mono_wasm_copy_managed_pointer(destinationAddress, source);
}
copy_to_address(destination) {
const sourceAddress = this.address;
wrapped_c_functions.mono_wasm_copy_managed_pointer(destination, sourceAddress);
}
get value() {
return this.get();
}
set value(value) {
this.set(value);
}
valueOf() {
throw new Error("Implicit conversion of roots to pointers is no longer supported. Use .value or .address as appropriate");
}
clear() {
this.set(0);
}
release() {
if (!this.__buffer)
throw new Error("No buffer");
const maxPooledInstances = 128;
if (_scratch_root_free_instances.length > maxPooledInstances) {
_mono_wasm_release_scratch_index(this.__index);
this.__buffer = null;
this.__index = 0;
}
else {
this.set(0);
_scratch_root_free_instances.push(this);
}
}
toString() {
return `[root @${this.address}]`;
}
}
class WasmExternalRoot {
constructor(address) {
this.__external_address = MonoObjectRefNull;
this.__external_address_32 = 0;
this._set_address(address);
}
_set_address(address) {
this.__external_address = address;
this.__external_address_32 = address >>> 2;
}
get address() {
return this.__external_address;
}
get_address() {
return this.__external_address;
}
get_address_32() {
return this.__external_address_32;
}
get() {
const result = Module.HEAPU32[this.__external_address_32];
return result;
}
set(value) {
wrapped_c_functions.mono_wasm_write_managed_pointer_unsafe(this.__external_address, value);
return value;
}
copy_from(source) {
const sourceAddress = source.address;
const destinationAddress = this.__external_address;
wrapped_c_functions.mono_wasm_copy_managed_pointer(destinationAddress, sourceAddress);
}
copy_to(destination) {
const sourceAddress = this.__external_address;
const destinationAddress = destination.address;
wrapped_c_functions.mono_wasm_copy_managed_pointer(destinationAddress, sourceAddress);
}
copy_from_address(source) {
const destinationAddress = this.__external_address;
wrapped_c_functions.mono_wasm_copy_managed_pointer(destinationAddress, source);
}
copy_to_address(destination) {
const sourceAddress = this.__external_address;
wrapped_c_functions.mono_wasm_copy_managed_pointer(destination, sourceAddress);
}
get value() {
return this.get();
}
set value(value) {
this.set(value);
}
valueOf() {
throw new Error("Implicit conversion of roots to pointers is no longer supported. Use .value or .address as appropriate");
}
clear() {
this.set(0);
}
release() {
const maxPooledInstances = 128;
if (_external_root_free_instances.length < maxPooledInstances)
_external_root_free_instances.push(this);
}
toString() {
return `[external root @${this.address}]`;
}
}
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// Code from JSIL:
// https://github.com/sq/JSIL/blob/1d57d5427c87ab92ffa3ca4b82429cd7509796ba/JSIL.Libraries/Includes/Bootstrap/Core/Classes/System.Convert.js#L149
// Thanks to Katelyn Gadd @kg
function toBase64StringImpl(inArray, offset, length) {
const reader = _makeByteReader(inArray, offset, length);
let result = "";
let ch1 = 0, ch2 = 0, ch3 = 0;
let bits = 0, equalsCount = 0, sum = 0;
const mask1 = (1 << 24) - 1, mask2 = (1 << 18) - 1, mask3 = (1 << 12) - 1, mask4 = (1 << 6) - 1;
const shift1 = 18, shift2 = 12, shift3 = 6, shift4 = 0;
for (;;) {
ch1 = reader.read();
ch2 = reader.read();
ch3 = reader.read();
if (ch1 === null)
break;
if (ch2 === null) {
ch2 = 0;
equalsCount += 1;
}
if (ch3 === null) {
ch3 = 0;
equalsCount += 1;
}
// Seems backwards, but is right!
sum = (ch1 << 16) | (ch2 << 8) | (ch3 << 0);
bits = (sum & mask1) >> shift1;
result += _base64Table[bits];
bits = (sum & mask2) >> shift2;
result += _base64Table[bits];
if (equalsCount < 2) {
bits = (sum & mask3) >> shift3;
result += _base64Table[bits];
}
if (equalsCount === 2) {
result += "==";
}
else if (equalsCount === 1) {
result += "=";
}
else {
bits = (sum & mask4) >> shift4;
result += _base64Table[bits];
}
}
return result;
}
const _base64Table = [
"A", "B", "C", "D",
"E", "F", "G", "H",
"I", "J", "K", "L",
"M", "N", "O", "P",
"Q", "R", "S", "T",
"U", "V", "W", "X",
"Y", "Z",
"a", "b", "c", "d",
"e", "f", "g", "h",
"i", "j", "k", "l",
"m", "n", "o", "p",
"q", "r", "s", "t",
"u", "v", "w", "x",
"y", "z",
"0", "1", "2", "3",
"4", "5", "6", "7",
"8", "9",
"+", "/"
];
function _makeByteReader(bytes, index, count) {
let position = (typeof (index) === "number") ? index : 0;
let endpoint;
if (typeof (count) === "number")
endpoint = (position + count);
else
endpoint = (bytes.length - position);
const result = {
read: function () {
if (position >= endpoint)
return null;
const nextByte = bytes[position];
position += 1;
return nextByte;
}
};
Object.defineProperty(result, "eof", {
get: function () {
return (position >= endpoint);
},
configurable: true,
enumerable: true
});
return result;
}
// Licensed to the .NET Foundation under one or more agreements.
const commands_received = new Map();
const wasm_func_map = new Map();
commands_received.remove = function (key) { const value = this.get(key); this.delete(key); return value; };
let _call_function_res_cache = {};
let _next_call_function_res_id = 0;
let _debugger_buffer_len = -1;
let _debugger_buffer;
let _assembly_name_str; //keep this variable, it's used by BrowserDebugProxy
let _entrypoint_method_token; //keep this variable, it's used by BrowserDebugProxy
const regexes = [];
// V8
// at <anonymous>:wasm-function[1900]:0x83f63
// at dlfree (<anonymous>:wasm-function[18739]:0x2328ef)
regexes.push(/at (?<replaceSection>[^:()]+:wasm-function\[(?<funcNum>\d+)\]:0x[a-fA-F\d]+)((?![^)a-fA-F\d])|$)/);
//# 5: WASM [009712b2], function #111 (''), pc=0x7c16595c973 (+0x53), pos=38740 (+11)
regexes.push(/(?:WASM \[[\da-zA-Z]+\], (?<replaceSection>function #(?<funcNum>[\d]+) \(''\)))/);
//# chrome
//# at http://127.0.0.1:63817/dotnet.wasm:wasm-function[8963]:0x1e23f4
regexes.push(/(?<replaceSection>[a-z]+:\/\/[^ )]*:wasm-function\[(?<funcNum>\d+)\]:0x[a-fA-F\d]+)/);
//# <?>.wasm-function[8962]
regexes.push(/(?<replaceSection><[^ >]+>[.:]wasm-function\[(?<funcNum>[0-9]+)\])/);
function mono_wasm_runtime_ready() {
runtimeHelpers.mono_wasm_runtime_is_ready = true;
// FIXME: where should this go?
_next_call_function_res_id = 0;
_call_function_res_cache = {};
_debugger_buffer_len = -1;
// DO NOT REMOVE - magic debugger init function
if (globalThis.dotnetDebugger)
// eslint-disable-next-line no-debugger
debugger;
else
console.debug("mono_wasm_runtime_ready", "fe00e07a-5519-4dfe-b35a-f867dbaf2e28");
_readSymbolMapFile("dotnet.js.symbols");
}
function mono_wasm_fire_debugger_agent_message() {
// eslint-disable-next-line no-debugger
debugger;
}
function mono_wasm_add_dbg_command_received(res_ok, id, buffer, buffer_len) {
const assembly_data = new Uint8Array(Module.HEAPU8.buffer, buffer, buffer_len);
const base64String = toBase64StringImpl(assembly_data);
const buffer_obj = {
res_ok,
res: {
id,
value: base64String
}
};
if (commands_received.has(id))
console.warn(`MONO_WASM: Adding an id (${id}) that already exists in commands_received`);
commands_received.set(id, buffer_obj);
}
function mono_wasm_malloc_and_set_debug_buffer(command_parameters) {
if (command_parameters.length > _debugger_buffer_len) {
if (_debugger_buffer)
Module._free(_debugger_buffer);
_debugger_buffer_len = Math.max(command_parameters.length, _debugger_buffer_len, 256);
_debugger_buffer = Module._malloc(_debugger_buffer_len);
}
const byteCharacters = atob(command_parameters);
for (let i = 0; i < byteCharacters.length; i++) {
Module.HEAPU8[_debugger_buffer + i] = byteCharacters.charCodeAt(i);
}
}
function mono_wasm_send_dbg_command_with_parms(id, command_set, command, command_parameters, length, valtype, newvalue) {
mono_wasm_malloc_and_set_debug_buffer(command_parameters);
wrapped_c_functions.mono_wasm_send_dbg_command_with_parms(id, command_set, command, _debugger_buffer, length, valtype, newvalue.toString());
const { res_ok, res } = commands_received.remove(id);
if (!res_ok)
throw new Error("Failed on mono_wasm_invoke_method_debugger_agent_with_parms");
return res;
}
function mono_wasm_send_dbg_command(id, command_set, command, command_parameters) {
mono_wasm_malloc_and_set_debug_buffer(command_parameters);
wrapped_c_functions.mono_wasm_send_dbg_command(id, command_set, command, _debugger_buffer, command_parameters.length);
const { res_ok, res } = commands_received.remove(id);
if (!res_ok)
throw new Error("Failed on mono_wasm_send_dbg_command");
return res;
}
function mono_wasm_get_dbg_command_info() {
const { res_ok, res } = commands_received.remove(0);
if (!res_ok)
throw new Error("Failed on mono_wasm_get_dbg_command_info");
return res;
}
function mono_wasm_debugger_resume() {
//nothing
}
function mono_wasm_detach_debugger() {
wrapped_c_functions.mono_wasm_set_is_debugger_attached(false);
}
function mono_wasm_change_debugger_log_level(level) {
wrapped_c_functions.mono_wasm_change_debugger_log_level(level);
}
/**
* Raises an event for the debug proxy
*/
function mono_wasm_raise_debug_event(event, args = {}) {
if (typeof event !== "object")
throw new Error(`event must be an object, but got ${JSON.stringify(event)}`);
if (event.eventName === undefined)
throw new Error(`event.eventName is a required parameter, in event: ${JSON.stringify(event)}`);
if (typeof args !== "object")
throw new Error(`args must be an object, but got ${JSON.stringify(args)}`);
console.debug("mono_wasm_debug_event_raised:aef14bca-5519-4dfe-b35a-f867abc123ae", JSON.stringify(event), JSON.stringify(args));
}
// Used by the debugger to enumerate loaded dlls and pdbs
function mono_wasm_get_loaded_files() {
return MONO$1.loaded_files;
}
function mono_wasm_wait_for_debugger() {
return new Promise((resolve) => {
const interval = setInterval(() => {
if (runtimeHelpers.wait_for_debugger != 1) {
return;
}
clearInterval(interval);
resolve();
}, 100);
});
}
function mono_wasm_debugger_attached() {
if (runtimeHelpers.wait_for_debugger == -1)
runtimeHelpers.wait_for_debugger = 1;
wrapped_c_functions.mono_wasm_set_is_debugger_attached(true);
}
function mono_wasm_set_entrypoint_breakpoint(assembly_name, entrypoint_method_token) {
//keep these assignments, these values are used by BrowserDebugProxy
_assembly_name_str = Module.UTF8ToString(assembly_name).concat(".dll");
_entrypoint_method_token = entrypoint_method_token;
//keep this console.assert, otherwise optimization will remove the assignments
console.assert(true, `Adding an entrypoint breakpoint ${_assembly_name_str} at method token ${_entrypoint_method_token}`);
// eslint-disable-next-line no-debugger
debugger;
}
function _create_proxy_from_object_id(objectId, details) {
if (objectId.startsWith("dotnet:array:")) {
let ret;
if (details.items === undefined) {
ret = details.map((p) => p.value);
return ret;
}
if (details.dimensionsDetails === undefined || details.dimensionsDetails.length === 1) {
ret = details.items.map((p) => p.value);
return ret;
}
}
const proxy = {};
Object.keys(details).forEach(p => {
const prop = details[p];
if (prop.get !== undefined) {
Object.defineProperty(proxy, prop.name, {
get() {
return mono_wasm_send_dbg_command(prop.get.id, prop.get.commandSet, prop.get.command, prop.get.buffer);
},
set: function (newValue) {
mono_wasm_send_dbg_command_with_parms(prop.set.id, prop.set.commandSet, prop.set.command, prop.set.buffer, prop.set.length, prop.set.valtype, newValue);
return true;
}
});
}
else if (prop.set !== undefined) {
Object.defineProperty(proxy, prop.name, {
get() {
return prop.value;
},
set: function (newValue) {
mono_wasm_send_dbg_command_with_parms(prop.set.id, prop.set.commandSet, prop.set.command, prop.set.buffer, prop.set.length, prop.set.valtype, newValue);
return true;
}
});
}
else {
proxy[prop.name] = prop.value;
}
});
return proxy;
}
function mono_wasm_call_function_on(request) {
if (request.arguments != undefined && !Array.isArray(request.arguments))
throw new Error(`"arguments" should be an array, but was ${request.arguments}`);
const objId = request.objectId;
const details = request.details;
let proxy = {};
if (objId.startsWith("dotnet:cfo_res:")) {
if (objId in _call_function_res_cache)
proxy = _call_function_res_cache[objId];
else
throw new Error(`Unknown object id ${objId}`);
}
else {
proxy = _create_proxy_from_object_id(objId, details);
}
const fn_args = request.arguments != undefined ? request.arguments.map(a => JSON.stringify(a.value)) : [];
const fn_body_template = `const fn = ${request.functionDeclaration}; return fn.apply(proxy, [${fn_args}]);`;
const fn_defn = new Function("proxy", fn_body_template);
const fn_res = fn_defn(proxy);
if (fn_res === undefined)
return { type: "undefined" };
if (Object(fn_res) !== fn_res) {
if (typeof (fn_res) == "object" && fn_res == null)
return { type: typeof (fn_res), subtype: `${fn_res}`, value: null };
return { type: typeof (fn_res), description: `${fn_res}`, value: `${fn_res}` };
}
if (request.returnByValue && fn_res.subtype == undefined)
return { type: "object", value: fn_res };
if (Object.getPrototypeOf(fn_res) == Array.prototype) {
const fn_res_id = _cache_call_function_res(fn_res);
return {
type: "object",
subtype: "array",
className: "Array",
description: `Array(${fn_res.length})`,
objectId: fn_res_id
};
}
if (fn_res.value !== undefined || fn_res.subtype !== undefined) {
return fn_res;
}
if (fn_res == proxy)
return { type: "object", className: "Object", description: "Object", objectId: objId };
const fn_res_id = _cache_call_function_res(fn_res);
return { type: "object", className: "Object", description: "Object", objectId: fn_res_id };
}
function _get_cfo_res_details(objectId, args) {
if (!(objectId in _call_function_res_cache))
throw new Error(`Could not find any object with id ${objectId}`);
const real_obj = _call_function_res_cache[objectId];
const descriptors = Object.getOwnPropertyDescriptors(real_obj);
if (args.accessorPropertiesOnly) {
Object.keys(descriptors).forEach(k => {
if (descriptors[k].get === undefined)
Reflect.deleteProperty(descriptors, k);
});
}
const res_details = [];
Object.keys(descriptors).forEach(k => {
let new_obj;
const prop_desc = descriptors[k];
if (typeof prop_desc.value == "object") {
// convert `{value: { type='object', ... }}`
// to `{ name: 'foo', value: { type='object', ... }}
new_obj = Object.assign({ name: k }, prop_desc);
}
else if (prop_desc.value !== undefined) {
// This is needed for values that were not added by us,
// thus are like { value: 5 }
// instead of { value: { type = 'number', value: 5 }}
//
// This can happen, for eg., when `length` gets added for arrays
// or `__proto__`.
new_obj = {
name: k,
// merge/add `type` and `description` to `d.value`
value: Object.assign({ type: (typeof prop_desc.value), description: "" + prop_desc.value }, prop_desc)
};
}
else if (prop_desc.get !== undefined) {
// The real_obj has the actual getter. We are just returning a placeholder
// If the caller tries to run function on the cfo_res object,
// that accesses this property, then it would be run on `real_obj`,
// which *has* the original getter
new_obj = {
name: k,
get: {
className: "Function",
description: `get ${k} () {}`,
type: "function"
}
};
}
else {
new_obj = { name: k, value: { type: "symbol", value: "<Unknown>", description: "<Unknown>" } };
}
res_details.push(new_obj);
});
return { __value_as_json_string__: JSON.stringify(res_details) };
}
function mono_wasm_get_details(objectId, args = {}) {
return _get_cfo_res_details(`dotnet:cfo_res:${objectId}`, args);
}
function _cache_call_function_res(obj) {
const id = `dotnet:cfo_res:${_next_call_function_res_id++}`;
_call_function_res_cache[id] = obj;
return id;
}
function mono_wasm_release_object(objectId) {
if (objectId in _call_function_res_cache)
delete _call_function_res_cache[objectId];
}
function mono_wasm_debugger_log(level, message_ptr) {
const message = Module.UTF8ToString(message_ptr);
if (INTERNAL$1["logging"] && typeof INTERNAL$1.logging["debugger"] === "function") {
INTERNAL$1.logging.debugger(level, message);
return;
}
if (Configuration === "Debug") {
console.debug(`MONO_WASM: Debugger.Debug: ${message}`);
}
}
function _readSymbolMapFile(filename) {
try {
const res = Module.FS_readFile(filename, { flags: "r", encoding: "utf8" });
res.split(/[\r\n]/).forEach((line) => {
const parts = line.split(/:/);
if (parts.length < 2)
return;
parts[1] = parts.splice(1).join(":");
wasm_func_map.set(Number(parts[0]), parts[1]);
});
if (Configuration === "Debug") {
console.debug(`MONO_WASM: Loaded ${wasm_func_map.size} symbols`);
}
}
catch (error) {
if (error.errno == 44) { // NOENT
if (Configuration === "Debug") {
console.debug(`MONO_WASM: Could not find symbols file ${filename}. Ignoring.`);
}
}
else {
console.log(`MONO_WASM: Error loading symbol file ${filename}: ${JSON.stringify(error)}`);
}
return;
}
}
function mono_wasm_symbolicate_string(message) {
try {
if (wasm_func_map.size == 0)
return message;
const origMessage = message;
for (let i = 0; i < regexes.length; i++) {
const newRaw = message.replace(new RegExp(regexes[i], "g"), (substring, ...args) => {
const groups = args.find(arg => {
return typeof (arg) == "object" && arg.replaceSection !== undefined;
});
if (groups === undefined)
return substring;
const funcNum = groups.funcNum;
const replaceSection = groups.replaceSection;
const name = wasm_func_map.get(Number(funcNum));
if (name === undefined)
return substring;
return substring.replace(replaceSection, `${name} (${replaceSection})`);
});
if (newRaw !== origMessage)
return newRaw;
}
return origMessage;
}
catch (error) {
console.debug(`MONO_WASM: failed to symbolicate: ${error}`);
return message;
}
}
function mono_wasm_stringify_as_error_with_stack(err) {
let errObj = err;
if (!(err instanceof Error))
errObj = new Error(err);
// Error
return mono_wasm_symbolicate_string(errObj.stack);
}
function mono_wasm_trace_logger(log_domain_ptr, log_level_ptr, message_ptr, fatal, user_data) {
const origMessage = Module.UTF8ToString(message_ptr);
const isFatal = !!fatal;
const domain = Module.UTF8ToString(log_domain_ptr);
const dataPtr = user_data;
const log_level = Module.UTF8ToString(log_level_ptr);
const message = `[MONO] ${origMessage}`;
if (INTERNAL$1["logging"] && typeof INTERNAL$1.logging["trace"] === "function") {
INTERNAL$1.logging.trace(domain, log_level, message, isFatal, dataPtr);
return;
}
switch (log_level) {
case "critical":
case "error":
console.error(mono_wasm_stringify_as_error_with_stack(message));
break;
case "warning":
console.warn(message);
break;
case "message":
console.log(message);
break;
case "info":
console.info(message);
break;
case "debug":
console.debug(message);
break;
default:
console.log(message);
break;
}
}
function setup_proxy_console(id, originalConsole, origin) {
function proxyConsoleMethod(prefix, func, asJson) {
return function (...args) {
try {
let payload = args[0];
if (payload === undefined)
payload = "undefined";
else if (payload === null)
payload = "null";
else if (typeof payload === "function")
payload = payload.toString();
else if (typeof payload !== "string") {
try {
payload = JSON.stringify(payload);
}
catch (e) {
payload = payload.toString();
}
}
if (typeof payload === "string")
payload = `[${id}] ${payload}`;
if (asJson) {
func(JSON.stringify({
method: prefix,
payload: payload,
arguments: args
}));
}
else {
func([prefix + payload, ...args.slice(1)]);
}
}
catch (err) {
originalConsole.error(`proxyConsole failed: ${err}`);
}
};
}
const originalConsoleObj = originalConsole;
const methods = ["debug", "trace", "warn", "info", "error"];
for (const m of methods) {
if (typeof (originalConsoleObj[m]) !== "function") {
originalConsoleObj[m] = proxyConsoleMethod(`console.${m}: `, originalConsole.log, false);
}
}
const consoleUrl = `${origin}/console`.replace("https://", "wss://").replace("http://", "ws://");
const consoleWebSocket = new WebSocket(consoleUrl);
consoleWebSocket.onopen = function () {
originalConsole.log(`browser: [${id}] Console websocket connected.`);
};
consoleWebSocket.onerror = function (event) {
originalConsole.error(`[${id}] websocket error: ${event}`, event);
};
consoleWebSocket.onclose = function (event) {
originalConsole.error(`[${id}] websocket closed: ${event}`, event);
};
const send = (msg) => {
if (consoleWebSocket.readyState === WebSocket.OPEN) {
consoleWebSocket.send(msg);
}
else {
originalConsole.log(msg);
}
};
// redirect output early, so that when emscripten starts it's already redirected
for (const m of ["log", ...methods])
originalConsoleObj[m] = proxyConsoleMethod(`console.${m}`, send, true);
}
// Licensed to the .NET Foundation under one or more agreements.
let num_icu_assets_loaded_successfully = 0;
// @offset must be the address of an ICU data archive in the native heap.
// returns true on success.
function mono_wasm_load_icu_data(offset) {
const ok = (wrapped_c_functions.mono_wasm_load_icu_data(offset)) === 1;
if (ok)
num_icu_assets_loaded_successfully++;
return ok;
}
// Get icudt.dat exact filename that matches given culture, examples:
// "ja" -> "icudt_CJK.dat"
// "en_US" (or "en-US" or just "en") -> "icudt_EFIGS.dat"
// etc, see "mono_wasm_get_icudt_name" implementation in pal_icushim_static.c
function mono_wasm_get_icudt_name(culture) {
return wrapped_c_functions.mono_wasm_get_icudt_name(culture);
}
// Performs setup for globalization.
// @globalization_mode is one of "icu", "invariant", or "auto".
// "auto" will use "icu" if any ICU data archives have been loaded,
// otherwise "invariant".
function mono_wasm_globalization_init() {
const config = Module.config;
let invariantMode = false;
if (!config.globalization_mode)
config.globalization_mode = "auto";
if (config.globalization_mode === "invariant")
invariantMode = true;
if (!invariantMode) {
if (num_icu_assets_loaded_successfully > 0) {
if (runtimeHelpers.diagnostic_tracing) {
console.debug("MONO_WASM: ICU data archive(s) loaded, disabling invariant mode");
}
}
else if (config.globalization_mode !== "icu") {
if (runtimeHelpers.diagnostic_tracing) {
console.debug("MONO_WASM: ICU data archive(s) not loaded, using invariant globalization mode");
}
invariantMode = true;
}
else {
const msg = "invariant globalization mode is inactive and no ICU data archives were loaded";
Module.printErr(`MONO_WASM: ERROR: ${msg}`);
throw new Error(msg);
}
}
if (invariantMode)
wrapped_c_functions.mono_wasm_setenv("DOTNET_SYSTEM_GLOBALIZATION_INVARIANT", "1");
// Set globalization mode to PredefinedCulturesOnly
wrapped_c_functions.mono_wasm_setenv("DOTNET_SYSTEM_GLOBALIZATION_PREDEFINED_CULTURES_ONLY", "1");
}
// Licensed to the .NET Foundation under one or more agreements.
// Initialize the AOT profiler with OPTIONS.
// Requires the AOT profiler to be linked into the app.
// options = { write_at: "<METHODNAME>", send_to: "<METHODNAME>" }
// <METHODNAME> should be in the format <CLASS>::<METHODNAME>.
// write_at defaults to 'WebAssembly.Runtime::StopProfile'.
// send_to defaults to 'WebAssembly.Runtime::DumpAotProfileData'.
// DumpAotProfileData stores the data into INTERNAL.aot_profile_data.
//
function mono_wasm_init_aot_profiler(options) {
if (options == null)
options = {};
if (!("write_at" in options))
options.write_at = "System.Runtime.InteropServices.JavaScript.JavaScriptExports::StopProfile";
if (!("send_to" in options))
options.send_to = "Interop/Runtime::DumpAotProfileData";
const arg = "aot:write-at-method=" + options.write_at + ",send-to-method=" + options.send_to;
Module.ccall("mono_wasm_load_profiler_aot", null, ["string"], [arg]);
}
// options = { write_at: "<METHODNAME>", send_to: "<METHODNAME>" }
// <METHODNAME> should be in the format <CLASS>::<METHODNAME>.
// write_at defaults to 'WebAssembly.Runtime::StopProfile'.
// send_to defaults to 'WebAssembly.Runtime::DumpCoverageProfileData'.
// DumpCoverageProfileData stores the data into INTERNAL.coverage_profile_data.
function mono_wasm_init_coverage_profiler(options) {
if (options == null)
options = {};
if (!("write_at" in options))
options.write_at = "WebAssembly.Runtime::StopProfile";
if (!("send_to" in options))
options.send_to = "WebAssembly.Runtime::DumpCoverageProfileData";
const arg = "coverage:write-at-method=" + options.write_at + ",send-to-method=" + options.send_to;
Module.ccall("mono_wasm_load_profiler_coverage", null, ["string"], [arg]);
}
// Licensed to the .NET Foundation under one or more agreements.
// TODO replace all of this with [JSExport]
const fn_signatures = [
["_get_cs_owned_object_by_js_handle_ref", "GetCSOwnedObjectByJSHandleRef", "iim"],
["_get_cs_owned_object_js_handle_ref", "GetCSOwnedObjectJSHandleRef", "mi"],
["_try_get_cs_owned_object_js_handle_ref", "TryGetCSOwnedObjectJSHandleRef", "mi"],
["_create_cs_owned_proxy_ref", "CreateCSOwnedProxyRef", "iiim"],
["_get_js_owned_object_by_gc_handle_ref", "GetJSOwnedObjectByGCHandleRef", "im"],
["_get_js_owned_object_gc_handle_ref", "GetJSOwnedObjectGCHandleRef", "m"],
["_release_js_owned_object_by_gc_handle", "ReleaseJSOwnedObjectByGCHandle", "i"],
["_create_tcs", "CreateTaskSource", ""],
["_create_task_callback", "CreateTaskCallback", ""],
["_set_tcs_result_ref", "SetTaskSourceResultRef", "iR"],
["_set_tcs_failure", "SetTaskSourceFailure", "is"],
["_get_tcs_task_ref", "GetTaskSourceTaskRef", "im"],
["_task_from_result_ref", "TaskFromResultRef", "Rm"],
["_setup_js_cont_ref", "SetupJSContinuationRef", "mo"],
["_object_to_string_ref", "ObjectToStringRef", "m"],
["_get_date_value_ref", "GetDateValueRef", "m"],
["_create_date_time_ref", "CreateDateTimeRef", "dm"],
["_create_uri_ref", "CreateUriRef", "sm"],
["_is_simple_array_ref", "IsSimpleArrayRef", "m"],
];
const wrapped_cs_functions = {};
for (const sig of fn_signatures) {
const wf = wrapped_cs_functions;
// lazy init on first run
wf[sig[0]] = function (...args) {
const fce = runtimeHelpers.bind_runtime_method(sig[1], sig[2]);
wf[sig[0]] = fce;
return fce(...args);
};
}
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
const _use_weak_ref = typeof globalThis.WeakRef === "function";
function create_weak_ref(js_obj) {
if (_use_weak_ref) {
return new WeakRef(js_obj);
}
else {
// this is trivial WeakRef replacement, which holds strong refrence, instead of weak one, when the browser doesn't support it
return {
deref: () => {
return js_obj;
}
};
}
}
// Licensed to the .NET Foundation under one or more agreements.
const _use_finalization_registry = typeof globalThis.FinalizationRegistry === "function";
let _js_owned_object_registry;
// this is array, not map. We maintain list of gaps in _js_handle_free_list so that it could be as compact as possible
const _cs_owned_objects_by_js_handle = [];
const _js_handle_free_list = [];
let _next_js_handle = 1;
const _js_owned_object_table = new Map();
// NOTE: FinalizationRegistry and WeakRef are missing on Safari below 14.1
if (_use_finalization_registry) {
_js_owned_object_registry = new globalThis.FinalizationRegistry(_js_owned_object_finalized);
}
const js_owned_gc_handle_symbol = Symbol.for("wasm js_owned_gc_handle");
const cs_owned_js_handle_symbol = Symbol.for("wasm cs_owned_js_handle");
function mono_wasm_get_jsobj_from_js_handle(js_handle) {
if (js_handle !== JSHandleNull && js_handle !== JSHandleDisposed)
return _cs_owned_objects_by_js_handle[js_handle];
return null;
}
// when should_add_in_flight === true, the JSObject would be temporarily hold by Normal gc_handle, so that it would not get collected during transition to the managed stack.
// its InFlight gc_handle would be freed when the instance arrives to managed side via Interop.Runtime.ReleaseInFlight
function get_cs_owned_object_by_js_handle_ref(js_handle, should_add_in_flight, result) {
if (js_handle === JSHandleNull || js_handle === JSHandleDisposed) {
setI32_unchecked(result, 0);
return;
}
wrapped_cs_functions._get_cs_owned_object_by_js_handle_ref(js_handle, should_add_in_flight ? 1 : 0, result);
}
function get_js_obj(js_handle) {
if (js_handle !== JSHandleNull && js_handle !== JSHandleDisposed)
return mono_wasm_get_jsobj_from_js_handle(js_handle);
return null;
}
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
function mono_wasm_get_js_handle(js_obj) {
if (js_obj[cs_owned_js_handle_symbol]) {
return js_obj[cs_owned_js_handle_symbol];
}
const js_handle = _js_handle_free_list.length ? _js_handle_free_list.pop() : _next_js_handle++;
// note _cs_owned_objects_by_js_handle is list, not Map. That's why we maintain _js_handle_free_list.
_cs_owned_objects_by_js_handle[js_handle] = js_obj;
if (Object.isExtensible(js_obj)) {
js_obj[cs_owned_js_handle_symbol] = js_handle;
}
// else
// The consequence of not adding the cs_owned_js_handle_symbol is, that we could have multiple JSHandles and multiple proxy instances.
// Throwing exception would prevent us from creating any proxy of non-extensible things.
// If we have weakmap instead, we would pay the price of the lookup for all proxies, not just non-extensible objects.
return js_handle;
}
function mono_wasm_release_cs_owned_object(js_handle) {
const obj = _cs_owned_objects_by_js_handle[js_handle];
if (typeof obj !== "undefined" && obj !== null) {
// if this is the global object then do not
// unregister it.
if (globalThis === obj)
return;
if (typeof obj[cs_owned_js_handle_symbol] !== "undefined") {
obj[cs_owned_js_handle_symbol] = undefined;
}
_cs_owned_objects_by_js_handle[js_handle] = undefined;
_js_handle_free_list.push(js_handle);
}
}
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
function setup_managed_proxy(result, gc_handle) {
// keep the gc_handle so that we could easily convert it back to original C# object for roundtrip
result[js_owned_gc_handle_symbol] = gc_handle;
// NOTE: this would be leaking C# objects when the browser doesn't support FinalizationRegistry/WeakRef
if (_use_finalization_registry) {
// register for GC of the C# object after the JS side is done with the object
_js_owned_object_registry.register(result, gc_handle, result);
}
// register for instance reuse
// NOTE: this would be leaking C# objects when the browser doesn't support FinalizationRegistry/WeakRef
const wr = create_weak_ref(result);
_js_owned_object_table.set(gc_handle, wr);
}
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
function teardown_managed_proxy(result, gc_handle) {
// The JS object associated with this gc_handle has been collected by the JS GC.
// As such, it's not possible for this gc_handle to be invoked by JS anymore, so
// we can release the tracking weakref (it's null now, by definition),
// and tell the C# side to stop holding a reference to the managed object.
// "The FinalizationRegistry callback is called potentially multiple times"
if (result) {
gc_handle = result[js_owned_gc_handle_symbol];
result[js_owned_gc_handle_symbol] = GCHandleNull;
if (_use_finalization_registry) {
_js_owned_object_registry.unregister(result);
}
}
if (gc_handle !== GCHandleNull && _js_owned_object_table.delete(gc_handle)) {
wrapped_cs_functions._release_js_owned_object_by_gc_handle(gc_handle);
}
}
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
function assert_not_disposed(result) {
const gc_handle = result[js_owned_gc_handle_symbol];
if (!(gc_handle != GCHandleNull)) throw new Error("Assert failed: ObjectDisposedException"); // inlined mono_assert
return gc_handle;
}
function _js_owned_object_finalized(gc_handle) {
teardown_managed_proxy(null, gc_handle);
}
function _lookup_js_owned_object(gc_handle) {
if (!gc_handle)
return null;
const wr = _js_owned_object_table.get(gc_handle);
if (wr) {
return wr.deref();
// TODO: could this be null before _js_owned_object_finalized was called ?
// TODO: are there race condition consequences ?
}
return null;
}
function get_js_owned_object_by_gc_handle_ref(gc_handle, result) {
if (!gc_handle) {
setI32_unchecked(result, 0);
return;
}
// this is always strong gc_handle
wrapped_cs_functions._get_js_owned_object_by_gc_handle_ref(gc_handle, result);
}
// Licensed to the .NET Foundation under one or more agreements.
class StringDecoder {
init_fields() {
if (!this.mono_wasm_string_decoder_buffer) {
this.mono_text_decoder = typeof TextDecoder !== "undefined" ? new TextDecoder("utf-16le") : null;
this.mono_wasm_string_root = mono_wasm_new_root();
this.mono_wasm_string_decoder_buffer = Module._malloc(12);
}
}
/**
* @deprecated Not GC or thread safe
*/
copy(mono_string) {
this.init_fields();
if (mono_string === MonoStringNull)
return null;
this.mono_wasm_string_root.value = mono_string;
const result = this.copy_root(this.mono_wasm_string_root);
this.mono_wasm_string_root.value = MonoStringNull;
return result;
}
copy_root(root) {
this.init_fields();
if (root.value === MonoStringNull)
return null;
const ppChars = this.mono_wasm_string_decoder_buffer + 0, pLengthBytes = this.mono_wasm_string_decoder_buffer + 4, pIsInterned = this.mono_wasm_string_decoder_buffer + 8;
wrapped_c_functions.mono_wasm_string_get_data_ref(root.address, ppChars, pLengthBytes, pIsInterned);
let result = undefined;
const lengthBytes = getI32(pLengthBytes), pChars = getU32(ppChars), isInterned = getI32(pIsInterned);
if (isInterned)
result = interned_string_table.get(root.value);
if (result === undefined) {
if (lengthBytes && pChars) {
result = this.decode(pChars, pChars + lengthBytes);
if (isInterned)
interned_string_table.set(root.value, result);
}
else
result = mono_wasm_empty_string;
}
if (result === undefined)
throw new Error(`internal error when decoding string at location ${root.value}`);
return result;
}
decode(start, end) {
let str = "";
if (this.mono_text_decoder) {
// When threading is enabled, TextDecoder does not accept a view of a
// SharedArrayBuffer, we must make a copy of the array first.
// See https://github.com/whatwg/encoding/issues/172
const subArray = typeof SharedArrayBuffer !== "undefined" && Module.HEAPU8.buffer instanceof SharedArrayBuffer
? Module.HEAPU8.slice(start, end)
: Module.HEAPU8.subarray(start, end);
str = this.mono_text_decoder.decode(subArray);
}
else {
for (let i = 0; i < end - start; i += 2) {
const char = Module.getValue(start + i, "i16");
str += String.fromCharCode(char);
}
}
return str;
}
}
const interned_string_table = new Map();
const interned_js_string_table = new Map();
let _empty_string_ptr = 0;
const _interned_string_full_root_buffers = [];
let _interned_string_current_root_buffer = null;
let _interned_string_current_root_buffer_count = 0;
const string_decoder = new StringDecoder();
const mono_wasm_empty_string = "";
/**
* @deprecated Not GC or thread safe
*/
function conv_string(mono_obj) {
return string_decoder.copy(mono_obj);
}
function conv_string_root(root) {
return string_decoder.copy_root(root);
}
// Ensures the string is already interned on both the managed and JavaScript sides,
// then returns the interned string value (to provide fast reference comparisons like C#)
function mono_intern_string(string) {
if (string.length === 0)
return mono_wasm_empty_string;
// HACK: This would normally be unsafe, but the return value of js_string_to_mono_string_interned is always an
// interned string, so the address will never change and it is safe for us to use the raw pointer. Don't do this though
const ptr = js_string_to_mono_string_interned(string);
const result = interned_string_table.get(ptr);
if (is_nullish(result))
throw new Error("internal error: interned_string_table did not contain string after js_string_to_mono_string_interned");
return result;
}
function _store_string_in_intern_table(string, root, internIt) {
if (!root.value)
throw new Error("null pointer passed to _store_string_in_intern_table");
const internBufferSize = 8192;
if (_interned_string_current_root_buffer_count >= internBufferSize) {
_interned_string_full_root_buffers.push(_interned_string_current_root_buffer);
_interned_string_current_root_buffer = null;
}
if (!_interned_string_current_root_buffer) {
_interned_string_current_root_buffer = mono_wasm_new_root_buffer(internBufferSize, "interned strings");
_interned_string_current_root_buffer_count = 0;
}
const rootBuffer = _interned_string_current_root_buffer;
const index = _interned_string_current_root_buffer_count++;
// Store the managed string into the managed intern table. This can theoretically
// provide a different managed object than the one we passed in, so update our
// pointer (stored in the root) with the result.
if (internIt) {
wrapped_c_functions.mono_wasm_intern_string_ref(root.address);
if (!root.value)
throw new Error("mono_wasm_intern_string_ref produced a null pointer");
}
interned_js_string_table.set(string, root.value);
interned_string_table.set(root.value, string);
if ((string.length === 0) && !_empty_string_ptr)
_empty_string_ptr = root.value;
// Copy the final pointer into our interned string root buffer to ensure the string
// remains rooted. TODO: Is this actually necessary?
rootBuffer.copy_value_from_address(index, root.address);
}
function js_string_to_mono_string_interned_root(string, result) {
let text;
if (typeof (string) === "symbol") {
text = string.description;
if (typeof (text) !== "string")
text = Symbol.keyFor(string);
if (typeof (text) !== "string")
text = "<unknown Symbol>";
}
else if (typeof (string) === "string") {
text = string;
}
if (typeof (text) !== "string") {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
throw new Error(`Argument to js_string_to_mono_string_interned must be a string but was ${string}`);
}
if ((text.length === 0) && _empty_string_ptr) {
result.set(_empty_string_ptr);
return;
}
const ptr = interned_js_string_table.get(text);
if (ptr) {
result.set(ptr);
return;
}
js_string_to_mono_string_new_root(text, result);
_store_string_in_intern_table(text, result, true);
}
function js_string_to_mono_string_root(string, result) {
result.clear();
if (string === null)
return;
else if (typeof (string) === "symbol")
js_string_to_mono_string_interned_root(string, result);
else if (typeof (string) !== "string")
throw new Error("Expected string argument, got " + typeof (string));
else if (string.length === 0)
// Always use an interned pointer for empty strings
js_string_to_mono_string_interned_root(string, result);
else {
// Looking up large strings in the intern table will require the JS runtime to
// potentially hash them and then do full byte-by-byte comparisons, which is
// very expensive. Because we can not guarantee it won't happen, try to minimize
// the cost of this and prevent performance issues for large strings
if (string.length <= 256) {
const interned = interned_js_string_table.get(string);
if (interned) {
result.set(interned);
return;
}
}
js_string_to_mono_string_new_root(string, result);
}
}
function js_string_to_mono_string_new_root(string, result) {
const buffer = Module._malloc((string.length + 1) * 2);
const buffer16 = (buffer >>> 1) | 0;
for (let i = 0; i < string.length; i++)
Module.HEAP16[buffer16 + i] = string.charCodeAt(i);
Module.HEAP16[buffer16 + string.length] = 0;
wrapped_c_functions.mono_wasm_string_from_utf16_ref(buffer, string.length, result.address);
Module._free(buffer);
}
/**
* @deprecated Not GC or thread safe
*/
function js_string_to_mono_string_interned(string) {
const temp = mono_wasm_new_root();
try {
js_string_to_mono_string_interned_root(string, temp);
return temp.value;
}
finally {
temp.release();
}
}
/**
* @deprecated Not GC or thread safe
*/
function js_string_to_mono_string(string) {
const temp = mono_wasm_new_root();
try {
js_string_to_mono_string_root(string, temp);
return temp.value;
}
finally {
temp.release();
}
}
/**
* @deprecated Not GC or thread safe
*/
function js_string_to_mono_string_new(string) {
const temp = mono_wasm_new_root();
try {
js_string_to_mono_string_new_root(string, temp);
return temp.value;
}
finally {
temp.release();
}
}
// Licensed to the .NET Foundation under one or more agreements.
/// a unique symbol used to mark a promise as controllable
const promise_control_symbol = Symbol.for("wasm promise_control");
/// Creates a new promise together with a controller that can be used to resolve or reject that promise.
/// Optionally takes callbacks to be called immediately after a promise is resolved or rejected.
function createPromiseController(afterResolve, afterReject) {
let promise_control = null;
const promise = new Promise(function (resolve, reject) {
promise_control = {
isDone: false,
promise: null,
resolve: (data) => {
if (!promise_control.isDone) {
promise_control.isDone = true;
resolve(data);
if (afterResolve) {
afterResolve();
}
}
},
reject: (reason) => {
if (!promise_control.isDone) {
promise_control.isDone = true;
reject(reason);
if (afterReject) {
afterReject();
}
}
}
};
});
promise_control.promise = promise;
const controllablePromise = promise;
controllablePromise[promise_control_symbol] = promise_control;
return { promise: controllablePromise, promise_control: promise_control };
}
function getPromiseController(promise) {
return promise[promise_control_symbol];
}
function isControllablePromise(promise) {
return promise[promise_control_symbol] !== undefined;
}
function assertIsControllablePromise(promise) {
if (!(isControllablePromise(promise))) throw new Error("Assert failed: Promise is not controllable"); // inlined mono_assert
}
// Licensed to the .NET Foundation under one or more agreements.
const _are_promises_supported = ((typeof Promise === "object") || (typeof Promise === "function")) && (typeof Promise.resolve === "function");
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
function isThenable(js_obj) {
// When using an external Promise library like Bluebird the Promise.resolve may not be sufficient
// to identify the object as a Promise.
return Promise.resolve(js_obj) === js_obj ||
((typeof js_obj === "object" || typeof js_obj === "function") && typeof js_obj.then === "function");
}
function wrap_as_cancelable_promise(fn) {
const { promise, promise_control } = createPromiseController();
const inner = fn();
inner.then((data) => promise_control.resolve(data)).catch((reason) => promise_control.reject(reason));
return promise;
}
function mono_wasm_cancel_promise(task_holder_gc_handle) {
const holder = _lookup_js_owned_object(task_holder_gc_handle);
if (!holder)
return; // probably already GC collected
const promise = holder.promise;
if (!(!!promise)) throw new Error(`Assert failed: Expected Promise for GCHandle ${task_holder_gc_handle}`); // inlined mono_assert
assertIsControllablePromise(promise);
const promise_control = getPromiseController(promise);
promise_control.reject("OperationCanceledException");
}
// Licensed to the .NET Foundation under one or more agreements.
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
function _js_to_mono_uri_root(should_add_in_flight, js_obj, result) {
switch (true) {
case js_obj === null:
case typeof js_obj === "undefined":
result.clear();
return;
case typeof js_obj === "symbol":
case typeof js_obj === "string":
wrapped_cs_functions._create_uri_ref(js_obj, result.address);
return;
default:
_extract_mono_obj_root(should_add_in_flight, js_obj, result);
return;
}
}
// this is only used from Blazor
/**
* @deprecated Not GC or thread safe. For blazor use only
*/
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
function js_to_mono_obj(js_obj) {
const temp = mono_wasm_new_root();
try {
js_to_mono_obj_root(js_obj, temp, false);
return temp.value;
}
finally {
temp.release();
}
}
/**
* @deprecated Not GC or thread safe
*/
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
function _js_to_mono_obj_unsafe(should_add_in_flight, js_obj) {
const temp = mono_wasm_new_root();
try {
js_to_mono_obj_root(js_obj, temp, should_add_in_flight);
return temp.value;
}
finally {
temp.release();
}
}
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
function js_to_mono_obj_root(js_obj, result, should_add_in_flight) {
if (is_nullish(result))
throw new Error("Expected (value, WasmRoot, boolean)");
switch (true) {
case js_obj === null:
case typeof js_obj === "undefined":
result.clear();
return;
case typeof js_obj === "number": {
let box_class;
if ((js_obj | 0) === js_obj) {
setI32_unchecked(runtimeHelpers._box_buffer, js_obj);
box_class = runtimeHelpers._class_int32;
}
else if ((js_obj >>> 0) === js_obj) {
setU32_unchecked(runtimeHelpers._box_buffer, js_obj);
box_class = runtimeHelpers._class_uint32;
}
else {
setF64(runtimeHelpers._box_buffer, js_obj);
box_class = runtimeHelpers._class_double;
}
wrapped_c_functions.mono_wasm_box_primitive_ref(box_class, runtimeHelpers._box_buffer, 8, result.address);
return;
}
case typeof js_obj === "string":
js_string_to_mono_string_root(js_obj, result);
return;
case typeof js_obj === "symbol":
js_string_to_mono_string_interned_root(js_obj, result);
return;
case typeof js_obj === "boolean":
setB32(runtimeHelpers._box_buffer, js_obj);
wrapped_c_functions.mono_wasm_box_primitive_ref(runtimeHelpers._class_boolean, runtimeHelpers._box_buffer, 4, result.address);
return;
case isThenable(js_obj) === true: {
_wrap_js_thenable_as_task_root(js_obj, result);
return;
}
case js_obj.constructor.name === "Date":
// getTime() is always UTC
wrapped_cs_functions._create_date_time_ref(js_obj.getTime(), result.address);
return;
default:
_extract_mono_obj_root(should_add_in_flight, js_obj, result);
return;
}
}
function _extract_mono_obj_root(should_add_in_flight, js_obj, result) {
result.clear();
if (js_obj === null || typeof js_obj === "undefined")
return;
if (js_obj[js_owned_gc_handle_symbol] !== undefined) {
// for js_owned_gc_handle we don't want to create new proxy
// since this is strong gc_handle we don't need to in-flight reference
assert_not_disposed(js_obj);
get_js_owned_object_by_gc_handle_ref(js_obj[js_owned_gc_handle_symbol], result.address);
return;
}
if (js_obj[cs_owned_js_handle_symbol]) {
get_cs_owned_object_by_js_handle_ref(js_obj[cs_owned_js_handle_symbol], should_add_in_flight, result.address);
// It's possible the managed object corresponding to this JS object was collected,
// in which case we need to make a new one.
// FIXME: This check is not thread safe
if (!result.value) {
delete js_obj[cs_owned_js_handle_symbol];
}
}
// FIXME: This check is not thread safe
if (!result.value) {
// Obtain the JS -> C# type mapping.
const wasm_type = js_obj[wasm_type_symbol];
const wasm_type_id = typeof wasm_type === "undefined" ? 0 : wasm_type;
const js_handle = mono_wasm_get_js_handle(js_obj);
wrapped_cs_functions._create_cs_owned_proxy_ref(js_handle, wasm_type_id, should_add_in_flight ? 1 : 0, result.address);
}
}
// https://github.com/Planeshifter/emscripten-examples/blob/master/01_PassingArrays/sum_post.js
function js_typedarray_to_heap(typedArray) {
const numBytes = typedArray.length * typedArray.BYTES_PER_ELEMENT;
const ptr = Module._malloc(numBytes);
const heapBytes = new Uint8Array(Module.HEAPU8.buffer, ptr, numBytes);
heapBytes.set(new Uint8Array(typedArray.buffer, typedArray.byteOffset, numBytes));
return heapBytes;
}
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
function js_typed_array_to_array_root(js_obj, result) {
// JavaScript typed arrays are array-like objects and provide a mechanism for accessing
// raw binary data. (...) To achieve maximum flexibility and efficiency, JavaScript typed arrays
// split the implementation into buffers and views. A buffer (implemented by the ArrayBuffer object)
// is an object representing a chunk of data; it has no format to speak of, and offers no
// mechanism for accessing its contents. In order to access the memory contained in a buffer,
// you need to use a view. A view provides a context - that is, a data type, starting offset,
// and number of elements - that turns the data into an actual typed array.
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Typed_arrays
if (has_backing_array_buffer(js_obj) && js_obj.BYTES_PER_ELEMENT) {
const arrayType = js_obj[wasm_type_symbol];
const heapBytes = js_typedarray_to_heap(js_obj);
wrapped_c_functions.mono_wasm_typed_array_new_ref(heapBytes.byteOffset, js_obj.length, js_obj.BYTES_PER_ELEMENT, arrayType, result.address);
Module._free(heapBytes.byteOffset);
}
else {
throw new Error("Object '" + js_obj + "' is not a typed array");
}
}
/**
* @deprecated Not GC or thread safe
*/
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
function js_typed_array_to_array(js_obj) {
const temp = mono_wasm_new_root();
try {
js_typed_array_to_array_root(js_obj, temp);
return temp.value;
}
finally {
temp.release();
}
}
// eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/explicit-module-boundary-types
function js_to_mono_enum(js_obj, method, parmIdx) {
if (typeof (js_obj) !== "number")
throw new Error(`Expected numeric value for enum argument, got '${js_obj}'`);
return js_obj | 0;
}
function js_array_to_mono_array(js_array, asString, should_add_in_flight) {
const arrayRoot = mono_wasm_new_root();
if (asString)
wrapped_c_functions.mono_wasm_string_array_new_ref(js_array.length, arrayRoot.address);
else
wrapped_c_functions.mono_wasm_obj_array_new_ref(js_array.length, arrayRoot.address);
const elemRoot = mono_wasm_new_root(MonoObjectNull);
const arrayAddress = arrayRoot.address;
const elemAddress = elemRoot.address;
try {
for (let i = 0; i < js_array.length; ++i) {
let obj = js_array[i];
if (asString)
obj = obj.toString();
js_to_mono_obj_root(obj, elemRoot, should_add_in_flight);
wrapped_c_functions.mono_wasm_obj_array_set_ref(arrayAddress, i, elemAddress);
}
return arrayRoot.value;
}
finally {
mono_wasm_release_roots(arrayRoot, elemRoot);
}
}
function _wrap_js_thenable_as_task_root(thenable, resultRoot) {
if (!thenable) {
resultRoot.clear();
return null;
}
// hold strong JS reference to thenable while in flight
// ideally, this should be hold alive by lifespan of the resulting C# Task, but this is good cheap aproximation
const thenable_js_handle = mono_wasm_get_js_handle(thenable);
// Note that we do not implement promise/task roundtrip.
// With more complexity we could recover original instance when this Task is marshaled back to JS.
// TODO optimization: return the tcs.Task on this same call instead of _get_tcs_task
const tcs_gc_handle = wrapped_cs_functions._create_tcs();
const holder = { tcs_gc_handle };
setup_managed_proxy(holder, tcs_gc_handle);
thenable.then((result) => {
wrapped_cs_functions._set_tcs_result_ref(tcs_gc_handle, result);
}, (reason) => {
wrapped_cs_functions._set_tcs_failure(tcs_gc_handle, reason ? reason.toString() : "");
}).finally(() => {
// let go of the thenable reference
mono_wasm_release_cs_owned_object(thenable_js_handle);
teardown_managed_proxy(holder, tcs_gc_handle); // this holds holder alive for finalizer, until the promise is freed
});
wrapped_cs_functions._get_tcs_task_ref(tcs_gc_handle, resultRoot.address);
// returns raw pointer to tcs.Task
return {
then_js_handle: thenable_js_handle,
};
}
function mono_wasm_typed_array_to_array_ref(js_handle, is_exception, result_address) {
const resultRoot = mono_wasm_new_external_root(result_address);
try {
const js_obj = mono_wasm_get_jsobj_from_js_handle(js_handle);
if (is_nullish(js_obj)) {
wrap_error_root(is_exception, "ERR06: Invalid JS object handle '" + js_handle + "'", resultRoot);
return;
}
// returns pointer to C# array
js_typed_array_to_array_root(js_obj, resultRoot);
}
catch (exc) {
wrap_error_root(is_exception, String(exc), resultRoot);
}
finally {
resultRoot.release();
}
}
// Licensed to the .NET Foundation under one or more agreements.
const cs_to_js_marshalers = new Map();
const js_to_cs_marshalers = new Map();
const bound_cs_function_symbol = Symbol.for("wasm bound_cs_function");
const bound_js_function_symbol = Symbol.for("wasm bound_js_function");
/**
* JSFunctionSignature is pointer to [
* Version: number,
* ArgumentCount: number,
* exc: { jsType: JsTypeFlags, type:MarshalerType, restype:MarshalerType, arg1type:MarshalerType, arg2type:MarshalerType, arg3type:MarshalerType}
* res: { jsType: JsTypeFlags, type:MarshalerType, restype:MarshalerType, arg1type:MarshalerType, arg2type:MarshalerType, arg3type:MarshalerType}
* arg1: { jsType: JsTypeFlags, type:MarshalerType, restype:MarshalerType, arg1type:MarshalerType, arg2type:MarshalerType, arg3type:MarshalerType}
* arg2: { jsType: JsTypeFlags, type:MarshalerType, restype:MarshalerType, arg1type:MarshalerType, arg2type:MarshalerType, arg3type:MarshalerType}
* ...
* ]
*
* Layout of the call stack frame buffers is array of JSMarshalerArgument
* JSMarshalerArguments is pointer to [
* exc: {type:MarshalerType, handle: IntPtr, data: Int64|Ref*|Void* },
* res: {type:MarshalerType, handle: IntPtr, data: Int64|Ref*|Void* },
* arg1: {type:MarshalerType, handle: IntPtr, data: Int64|Ref*|Void* },
* arg2: {type:MarshalerType, handle: IntPtr, data: Int64|Ref*|Void* },
* ...
* ]
*/
const JavaScriptMarshalerArgSize = 16;
const JSMarshalerTypeSize = 32;
const JSMarshalerSignatureHeaderSize = 4 + 4; // without Exception and Result
function get_arg(args, index) {
if (!(args)) throw new Error("Assert failed: Null args"); // inlined mono_assert
return args + (index * JavaScriptMarshalerArgSize);
}
function is_args_exception(args) {
if (!(args)) throw new Error("Assert failed: Null args"); // inlined mono_assert
const exceptionType = get_arg_type(args);
return exceptionType !== MarshalerType.None;
}
function get_sig(signature, index) {
if (!(signature)) throw new Error("Assert failed: Null signatures"); // inlined mono_assert
return signature + (index * JSMarshalerTypeSize) + JSMarshalerSignatureHeaderSize;
}
function get_signature_type(sig) {
if (!(sig)) throw new Error("Assert failed: Null sig"); // inlined mono_assert
return getU32(sig);
}
function get_signature_res_type(sig) {
if (!(sig)) throw new Error("Assert failed: Null sig"); // inlined mono_assert
return getU32(sig + 16);
}
function get_signature_custom_code(sig) {
if (!(sig)) throw new Error("Assert failed: Null sig"); // inlined mono_assert
return getU32(sig + 8);
}
function get_signature_custom_code_len(sig) {
if (!(sig)) throw new Error("Assert failed: Null sig"); // inlined mono_assert
return getU32(sig + 12);
}
function get_signature_arg1_type(sig) {
if (!(sig)) throw new Error("Assert failed: Null sig"); // inlined mono_assert
return getU32(sig + 20);
}
function get_signature_arg2_type(sig) {
if (!(sig)) throw new Error("Assert failed: Null sig"); // inlined mono_assert
return getU32(sig + 24);
}
function get_signature_arg3_type(sig) {
if (!(sig)) throw new Error("Assert failed: Null sig"); // inlined mono_assert
return getU32(sig + 28);
}
function get_signature_argument_count(signature) {
if (!(signature)) throw new Error("Assert failed: Null signatures"); // inlined mono_assert
return getI32(signature + 4);
}
function get_signature_version(signature) {
if (!(signature)) throw new Error("Assert failed: Null signatures"); // inlined mono_assert
return getI32(signature);
}
function get_sig_type(sig) {
if (!(sig)) throw new Error("Assert failed: Null signatures"); // inlined mono_assert
return getU32(sig);
}
function get_arg_type(arg) {
if (!(arg)) throw new Error("Assert failed: Null arg"); // inlined mono_assert
const type = getU32(arg + 12);
return type;
}
function get_arg_element_type(arg) {
if (!(arg)) throw new Error("Assert failed: Null arg"); // inlined mono_assert
const type = getU32(arg + 4);
return type;
}
function set_arg_type(arg, type) {
if (!(arg)) throw new Error("Assert failed: Null arg"); // inlined mono_assert
setU32(arg + 12, type);
}
function set_arg_element_type(arg, type) {
if (!(arg)) throw new Error("Assert failed: Null arg"); // inlined mono_assert
setU32(arg + 4, type);
}
function get_arg_b8(arg) {
if (!(arg)) throw new Error("Assert failed: Null arg"); // inlined mono_assert
return !!getU8(arg);
}
function get_arg_u8(arg) {
if (!(arg)) throw new Error("Assert failed: Null arg"); // inlined mono_assert
return getU8(arg);
}
function get_arg_u16(arg) {
if (!(arg)) throw new Error("Assert failed: Null arg"); // inlined mono_assert
return getU16(arg);
}
function get_arg_i16(arg) {
if (!(arg)) throw new Error("Assert failed: Null arg"); // inlined mono_assert
return getI16(arg);
}
function get_arg_i32(arg) {
if (!(arg)) throw new Error("Assert failed: Null arg"); // inlined mono_assert
return getI32(arg);
}
function get_arg_intptr(arg) {
if (!(arg)) throw new Error("Assert failed: Null arg"); // inlined mono_assert
return getU32(arg);
}
function get_arg_i52(arg) {
if (!(arg)) throw new Error("Assert failed: Null arg"); // inlined mono_assert
// we know that the range check and conversion from Int64 was be done on C# side
return getF64(arg);
}
function get_arg_i64_big(arg) {
if (!(arg)) throw new Error("Assert failed: Null arg"); // inlined mono_assert
return getI64Big(arg);
}
function get_arg_date(arg) {
if (!(arg)) throw new Error("Assert failed: Null arg"); // inlined mono_assert
const unixTime = getF64(arg);
const date = new Date(unixTime);
return date;
}
function get_arg_f32(arg) {
if (!(arg)) throw new Error("Assert failed: Null arg"); // inlined mono_assert
return getF32(arg);
}
function get_arg_f64(arg) {
if (!(arg)) throw new Error("Assert failed: Null arg"); // inlined mono_assert
return getF64(arg);
}
function set_arg_b8(arg, value) {
if (!(arg)) throw new Error("Assert failed: Null arg"); // inlined mono_assert
if (!(typeof value === "boolean")) throw new Error(`Assert failed: Value is not a Boolean: ${value} (${typeof (value)})`); // inlined mono_assert
setU8(arg, value ? 1 : 0);
}
function set_arg_u8(arg, value) {
if (!(arg)) throw new Error("Assert failed: Null arg"); // inlined mono_assert
setU8(arg, value);
}
function set_arg_u16(arg, value) {
if (!(arg)) throw new Error("Assert failed: Null arg"); // inlined mono_assert
setU16(arg, value);
}
function set_arg_i16(arg, value) {
if (!(arg)) throw new Error("Assert failed: Null arg"); // inlined mono_assert
setI16(arg, value);
}
function set_arg_i32(arg, value) {
if (!(arg)) throw new Error("Assert failed: Null arg"); // inlined mono_assert
setI32(arg, value);
}
function set_arg_intptr(arg, value) {
if (!(arg)) throw new Error("Assert failed: Null arg"); // inlined mono_assert
setU32(arg, value);
}
function set_arg_i52(arg, value) {
if (!(arg)) throw new Error("Assert failed: Null arg"); // inlined mono_assert
if (!(Number.isSafeInteger(value))) throw new Error(`Assert failed: Value is not an integer: ${value} (${typeof (value)})`); // inlined mono_assert
// we know that conversion to Int64 would be done on C# side
setF64(arg, value);
}
function set_arg_i64_big(arg, value) {
if (!(arg)) throw new Error("Assert failed: Null arg"); // inlined mono_assert
setI64Big(arg, value);
}
function set_arg_date(arg, value) {
if (!(arg)) throw new Error("Assert failed: Null arg"); // inlined mono_assert
// getTime() is always UTC
const unixTime = value.getTime();
setF64(arg, unixTime);
}
function set_arg_f64(arg, value) {
if (!(arg)) throw new Error("Assert failed: Null arg"); // inlined mono_assert
setF64(arg, value);
}
function set_arg_f32(arg, value) {
if (!(arg)) throw new Error("Assert failed: Null arg"); // inlined mono_assert
setF32(arg, value);
}
function get_arg_js_handle(arg) {
if (!(arg)) throw new Error("Assert failed: Null arg"); // inlined mono_assert
return getU32(arg + 4);
}
function set_js_handle(arg, jsHandle) {
if (!(arg)) throw new Error("Assert failed: Null arg"); // inlined mono_assert
setU32(arg + 4, jsHandle);
}
function get_arg_gc_handle(arg) {
if (!(arg)) throw new Error("Assert failed: Null arg"); // inlined mono_assert
return getU32(arg + 4);
}
function set_gc_handle(arg, gcHandle) {
if (!(arg)) throw new Error("Assert failed: Null arg"); // inlined mono_assert
setU32(arg + 4, gcHandle);
}
function get_string_root(arg) {
if (!(arg)) throw new Error("Assert failed: Null arg"); // inlined mono_assert
return mono_wasm_new_external_root(arg);
}
function get_arg_length(arg) {
if (!(arg)) throw new Error("Assert failed: Null arg"); // inlined mono_assert
return getI32(arg + 8);
}
function set_arg_length(arg, size) {
if (!(arg)) throw new Error("Assert failed: Null arg"); // inlined mono_assert
setI32(arg + 8, size);
}
function set_root(arg, root) {
if (!(arg)) throw new Error("Assert failed: Null arg"); // inlined mono_assert
setU32(arg + 0, root.get_address());
}
class ManagedObject {
dispose() {
teardown_managed_proxy(this, GCHandleNull);
}
get isDisposed() {
return this[js_owned_gc_handle_symbol] === GCHandleNull;
}
toString() {
return `CsObject(gc_handle: ${this[js_owned_gc_handle_symbol]})`;
}
}
class ManagedError extends Error {
constructor(message) {
super(message);
}
get stack() {
//todo implement lazy managed stack strace from this[js_owned_gc_handle_symbol]!
return super.stack;
}
dispose() {
teardown_managed_proxy(this, GCHandleNull);
}
get isDisposed() {
return this[js_owned_gc_handle_symbol] === GCHandleNull;
}
toString() {
return `ManagedError(gc_handle: ${this[js_owned_gc_handle_symbol]})`;
}
}
function get_signature_marshaler(signature, index) {
if (!(signature)) throw new Error("Assert failed: Null signatures"); // inlined mono_assert
const sig = get_sig(signature, index);
return getU32(sig + 8);
}
function array_element_size(element_type) {
return element_type == MarshalerType.Byte ? 1
: element_type == MarshalerType.Int32 ? 4
: element_type == MarshalerType.Int52 ? 8
: element_type == MarshalerType.Double ? 8
: element_type == MarshalerType.String ? JavaScriptMarshalerArgSize
: element_type == MarshalerType.Object ? JavaScriptMarshalerArgSize
: element_type == MarshalerType.JSObject ? JavaScriptMarshalerArgSize
: -1;
}
class MemoryView {
constructor(_pointer, _length, _viewType) {
this._pointer = _pointer;
this._length = _length;
this._viewType = _viewType;
}
_unsafe_create_view() {
// this view must be short lived so that it doesn't fail after wasm memory growth
// for that reason we also don't give the view out to end user and provide set/slice/copyTo API instead
const view = this._viewType == 0 /* MemoryViewType.Byte */ ? new Uint8Array(Module.HEAPU8.buffer, this._pointer, this._length)
: this._viewType == 1 /* MemoryViewType.Int32 */ ? new Int32Array(Module.HEAP32.buffer, this._pointer, this._length)
: this._viewType == 2 /* MemoryViewType.Double */ ? new Float64Array(Module.HEAPF64.buffer, this._pointer, this._length)
: null;
if (!view)
throw new Error("NotImplementedException");
return view;
}
set(source, targetOffset) {
if (!(!this.isDisposed)) throw new Error("Assert failed: ObjectDisposedException"); // inlined mono_assert
const targetView = this._unsafe_create_view();
if (!(source && targetView && source.constructor === targetView.constructor)) throw new Error(`Assert failed: Expected ${targetView.constructor}`); // inlined mono_assert
targetView.set(source, targetOffset);
// TODO consider memory write barrier
}
copyTo(target, sourceOffset) {
if (!(!this.isDisposed)) throw new Error("Assert failed: ObjectDisposedException"); // inlined mono_assert
const sourceView = this._unsafe_create_view();
if (!(target && sourceView && target.constructor === sourceView.constructor)) throw new Error(`Assert failed: Expected ${sourceView.constructor}`); // inlined mono_assert
const trimmedSource = sourceView.subarray(sourceOffset);
// TODO consider memory read barrier
target.set(trimmedSource);
}
slice(start, end) {
if (!(!this.isDisposed)) throw new Error("Assert failed: ObjectDisposedException"); // inlined mono_assert
const sourceView = this._unsafe_create_view();
// TODO consider memory read barrier
return sourceView.slice(start, end);
}
get length() {
if (!(!this.isDisposed)) throw new Error("Assert failed: ObjectDisposedException"); // inlined mono_assert
return this._length;
}
get byteLength() {
if (!(!this.isDisposed)) throw new Error("Assert failed: ObjectDisposedException"); // inlined mono_assert
return this._viewType == 0 /* MemoryViewType.Byte */ ? this._length
: this._viewType == 1 /* MemoryViewType.Int32 */ ? this._length << 2
: this._viewType == 2 /* MemoryViewType.Double */ ? this._length << 3
: 0;
}
}
class Span extends MemoryView {
constructor(pointer, length, viewType) {
super(pointer, length, viewType);
this.is_disposed = false;
}
dispose() {
this.is_disposed = true;
}
get isDisposed() {
return this.is_disposed;
}
}
class ArraySegment extends MemoryView {
constructor(pointer, length, viewType) {
super(pointer, length, viewType);
}
dispose() {
teardown_managed_proxy(this, GCHandleNull);
}
get isDisposed() {
return this[js_owned_gc_handle_symbol] === GCHandleNull;
}
}
// please keep in sync with src\libraries\System.Runtime.InteropServices.JavaScript\src\System\Runtime\InteropServices\JavaScript\MarshalerType.cs
var MarshalerType;
(function (MarshalerType) {
MarshalerType[MarshalerType["None"] = 0] = "None";
MarshalerType[MarshalerType["Void"] = 1] = "Void";
MarshalerType[MarshalerType["Discard"] = 2] = "Discard";
MarshalerType[MarshalerType["Boolean"] = 3] = "Boolean";
MarshalerType[MarshalerType["Byte"] = 4] = "Byte";
MarshalerType[MarshalerType["Char"] = 5] = "Char";
MarshalerType[MarshalerType["Int16"] = 6] = "Int16";
MarshalerType[MarshalerType["Int32"] = 7] = "Int32";
MarshalerType[MarshalerType["Int52"] = 8] = "Int52";
MarshalerType[MarshalerType["BigInt64"] = 9] = "BigInt64";
MarshalerType[MarshalerType["Double"] = 10] = "Double";
MarshalerType[MarshalerType["Single"] = 11] = "Single";
MarshalerType[MarshalerType["IntPtr"] = 12] = "IntPtr";
MarshalerType[MarshalerType["JSObject"] = 13] = "JSObject";
MarshalerType[MarshalerType["Object"] = 14] = "Object";
MarshalerType[MarshalerType["String"] = 15] = "String";
MarshalerType[MarshalerType["Exception"] = 16] = "Exception";
MarshalerType[MarshalerType["DateTime"] = 17] = "DateTime";
MarshalerType[MarshalerType["DateTimeOffset"] = 18] = "DateTimeOffset";
MarshalerType[MarshalerType["Nullable"] = 19] = "Nullable";
MarshalerType[MarshalerType["Task"] = 20] = "Task";
MarshalerType[MarshalerType["Array"] = 21] = "Array";
MarshalerType[MarshalerType["ArraySegment"] = 22] = "ArraySegment";
MarshalerType[MarshalerType["Span"] = 23] = "Span";
MarshalerType[MarshalerType["Action"] = 24] = "Action";
MarshalerType[MarshalerType["Function"] = 25] = "Function";
// only on runtime
MarshalerType[MarshalerType["JSException"] = 26] = "JSException";
})(MarshalerType || (MarshalerType = {}));
// Licensed to the .NET Foundation under one or more agreements.
const delegate_invoke_symbol = Symbol.for("wasm delegate_invoke");
const delegate_invoke_signature_symbol = Symbol.for("wasm delegate_invoke_signature");
// this is only used from Blazor
function unbox_mono_obj(mono_obj) {
if (mono_obj === MonoObjectNull)
return undefined;
const root = mono_wasm_new_root(mono_obj);
try {
return unbox_mono_obj_root(root);
}
finally {
root.release();
}
}
function _unbox_cs_owned_root_as_js_object(root) {
// we don't need in-flight reference as we already have it rooted here
const js_handle = wrapped_cs_functions._get_cs_owned_object_js_handle_ref(root.address, 0);
const js_obj = mono_wasm_get_jsobj_from_js_handle(js_handle);
return js_obj;
}
// eslint-disable-next-line @typescript-eslint/no-unused-vars
function _unbox_mono_obj_root_with_known_nonprimitive_type_impl(root, type, typePtr, unbox_buffer) {
//See MARSHAL_TYPE_ defines in driver.c
switch (type) {
case 0 /* MarshalType.NULL */:
return null;
case 26 /* MarshalType.INT64 */:
case 27 /* MarshalType.UINT64 */:
// TODO: Fix this once emscripten offers HEAPI64/HEAPU64 or can return them
throw new Error("int64 not available");
case 3 /* MarshalType.STRING */:
case 29 /* MarshalType.STRING_INTERNED */:
return conv_string_root(root);
case 4 /* MarshalType.VT */:
throw new Error("no idea on how to unbox value types");
case 5 /* MarshalType.DELEGATE */:
return _wrap_delegate_root_as_function(root);
case 6 /* MarshalType.TASK */:
return _unbox_task_root_as_promise(root);
case 7 /* MarshalType.OBJECT */:
return _unbox_ref_type_root_as_js_object(root);
case 10 /* MarshalType.ARRAY_BYTE */:
case 11 /* MarshalType.ARRAY_UBYTE */:
case 12 /* MarshalType.ARRAY_UBYTE_C */:
case 13 /* MarshalType.ARRAY_SHORT */:
case 14 /* MarshalType.ARRAY_USHORT */:
case 15 /* MarshalType.ARRAY_INT */:
case 16 /* MarshalType.ARRAY_UINT */:
case 17 /* MarshalType.ARRAY_FLOAT */:
case 18 /* MarshalType.ARRAY_DOUBLE */:
throw new Error("Marshaling of primitive arrays are not supported.");
case 20: // clr .NET DateTime
return new Date(wrapped_cs_functions._get_date_value_ref(root.address));
case 21: // clr .NET DateTimeOffset
return wrapped_cs_functions._object_to_string_ref(root.address);
case 22 /* MarshalType.URI */:
return wrapped_cs_functions._object_to_string_ref(root.address);
case 23 /* MarshalType.SAFEHANDLE */:
return _unbox_cs_owned_root_as_js_object(root);
case 30 /* MarshalType.VOID */:
return undefined;
default:
throw new Error(`no idea on how to unbox object of MarshalType ${type} at offset ${root.value} (root address is ${root.address})`);
}
}
function _unbox_mono_obj_root_with_known_nonprimitive_type(root, type, unbox_buffer) {
if (type >= 512 /* MarshalError.FIRST */)
throw new Error(`Got marshaling error ${type} when attempting to unbox object at address ${root.value} (root located at ${root.address})`);
let typePtr = MonoTypeNull;
if ((type === 4 /* MarshalType.VT */) || (type == 7 /* MarshalType.OBJECT */)) {
typePtr = getU32(unbox_buffer);
if (typePtr < 1024)
throw new Error(`Got invalid MonoType ${typePtr} for object at address ${root.value} (root located at ${root.address})`);
}
return _unbox_mono_obj_root_with_known_nonprimitive_type_impl(root, type, typePtr, unbox_buffer);
}
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
function unbox_mono_obj_root(root) {
if (root.value === 0)
return undefined;
const unbox_buffer = runtimeHelpers._unbox_buffer;
const type = wrapped_c_functions.mono_wasm_try_unbox_primitive_and_get_type_ref(root.address, unbox_buffer, runtimeHelpers._unbox_buffer_size);
switch (type) {
case 1 /* MarshalType.INT */:
return getI32(unbox_buffer);
case 25 /* MarshalType.UINT32 */:
return getU32(unbox_buffer);
case 32 /* MarshalType.POINTER */:
// FIXME: Is this right?
return getU32(unbox_buffer);
case 24 /* MarshalType.FP32 */:
return getF32(unbox_buffer);
case 2 /* MarshalType.FP64 */:
return getF64(unbox_buffer);
case 8 /* MarshalType.BOOL */:
return (getI32(unbox_buffer)) !== 0;
case 28 /* MarshalType.CHAR */:
return String.fromCharCode(getI32(unbox_buffer));
case 0 /* MarshalType.NULL */:
return null;
default:
return _unbox_mono_obj_root_with_known_nonprimitive_type(root, type, unbox_buffer);
}
}
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
function mono_array_to_js_array(mono_array) {
if (mono_array === MonoArrayNull)
return null;
const arrayRoot = mono_wasm_new_root(mono_array);
try {
return mono_array_root_to_js_array(arrayRoot);
}
finally {
arrayRoot.release();
}
}
function is_nested_array_ref(ele) {
return wrapped_cs_functions._is_simple_array_ref(ele.address);
}
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
function mono_array_root_to_js_array(arrayRoot) {
if (arrayRoot.value === MonoArrayNull)
return null;
const arrayAddress = arrayRoot.address;
const elemRoot = mono_wasm_new_root();
const elemAddress = elemRoot.address;
try {
const len = wrapped_c_functions.mono_wasm_array_length(arrayRoot.value);
const res = new Array(len);
for (let i = 0; i < len; ++i) {
// TODO: pass arrayRoot.address and elemRoot.address into new API that copies
wrapped_c_functions.mono_wasm_array_get_ref(arrayAddress, i, elemAddress);
if (is_nested_array_ref(elemRoot))
res[i] = mono_array_root_to_js_array(elemRoot);
else
res[i] = unbox_mono_obj_root(elemRoot);
}
return res;
}
finally {
elemRoot.release();
}
}
function _wrap_delegate_root_as_function(root) {
if (root.value === MonoObjectNull)
return null;
// get strong reference to the Delegate
const gc_handle = wrapped_cs_functions._get_js_owned_object_gc_handle_ref(root.address);
return _wrap_delegate_gc_handle_as_function(gc_handle);
}
function _wrap_delegate_gc_handle_as_function(gc_handle, after_listener_callback) {
// see if we have js owned instance for this gc_handle already
let result = _lookup_js_owned_object(gc_handle);
// If the function for this gc_handle was already collected (or was never created)
if (!result) {
// note that we do not implement function/delegate roundtrip
result = function (...args) {
const delegateRoot = mono_wasm_new_root();
get_js_owned_object_by_gc_handle_ref(gc_handle, delegateRoot.address);
try {
// FIXME: Pass delegateRoot by-ref
const res = call_method_ref(result[delegate_invoke_symbol], delegateRoot, result[delegate_invoke_signature_symbol], args);
if (after_listener_callback) {
after_listener_callback();
}
return res;
}
finally {
delegateRoot.release();
}
};
// bind the method
const delegateRoot = mono_wasm_new_root();
get_js_owned_object_by_gc_handle_ref(gc_handle, delegateRoot.address);
try {
if (typeof result[delegate_invoke_symbol] === "undefined") {
result[delegate_invoke_symbol] = wrapped_c_functions.mono_wasm_get_delegate_invoke_ref(delegateRoot.address);
if (!result[delegate_invoke_symbol]) {
throw new Error("System.Delegate Invoke method can not be resolved.");
}
}
if (typeof result[delegate_invoke_signature_symbol] === "undefined") {
result[delegate_invoke_signature_symbol] = mono_method_get_call_signature_ref(result[delegate_invoke_symbol], delegateRoot);
}
}
finally {
delegateRoot.release();
}
setup_managed_proxy(result, gc_handle);
}
return result;
}
function mono_wasm_create_cs_owned_object_ref(core_name, args, is_exception, result_address) {
const argsRoot = mono_wasm_new_external_root(args), nameRoot = mono_wasm_new_external_root(core_name), resultRoot = mono_wasm_new_external_root(result_address);
try {
const js_name = conv_string_root(nameRoot);
if (!js_name) {
wrap_error_root(is_exception, "Invalid name @" + nameRoot.value, resultRoot);
return;
}
const coreObj = globalThis[js_name];
if (coreObj === null || typeof coreObj === "undefined") {
wrap_error_root(is_exception, "JavaScript host object '" + js_name + "' not found.", resultRoot);
return;
}
try {
const js_args = mono_array_root_to_js_array(argsRoot);
// This is all experimental !!!!!!
const allocator = function (constructor, js_args) {
// Not sure if we should be checking for anything here
let argsList = [];
argsList[0] = constructor;
if (js_args)
argsList = argsList.concat(js_args);
// eslint-disable-next-line prefer-spread
const tempCtor = constructor.bind.apply(constructor, argsList);
const js_obj = new tempCtor();
return js_obj;
};
const js_obj = allocator(coreObj, js_args);
const js_handle = mono_wasm_get_js_handle(js_obj);
// returns boxed js_handle int, because on exception we need to return String on same method signature
// here we don't have anything to in-flight reference, as the JSObject doesn't exist yet
js_to_mono_obj_root(js_handle, resultRoot, false);
}
catch (ex) {
wrap_error_root(is_exception, ex, resultRoot);
return;
}
}
finally {
resultRoot.release();
argsRoot.release();
nameRoot.release();
}
}
function _unbox_task_root_as_promise(root) {
if (root.value === MonoObjectNull)
return null;
if (!_are_promises_supported)
throw new Error("Promises are not supported thus 'System.Threading.Tasks.Task' can not work in this context.");
// get strong reference to Task
const gc_handle = wrapped_cs_functions._get_js_owned_object_gc_handle_ref(root.address);
// see if we have js owned instance for this gc_handle already
let result = _lookup_js_owned_object(gc_handle);
// If the promise for this gc_handle was already collected (or was never created)
if (!result) {
const explicitFinalization = () => teardown_managed_proxy(result, gc_handle);
const { promise, promise_control } = createPromiseController(explicitFinalization, explicitFinalization);
// note that we do not implement promise/task roundtrip
// With more complexity we could recover original instance when this promise is marshaled back to C#.
result = promise;
// register C# side of the continuation
wrapped_cs_functions._setup_js_cont_ref(root.address, promise_control);
setup_managed_proxy(result, gc_handle);
}
return result;
}
function _unbox_ref_type_root_as_js_object(root) {
if (root.value === MonoObjectNull)
return null;
// this could be JSObject proxy of a js native object
// we don't need in-flight reference as we already have it rooted here
const js_handle = wrapped_cs_functions._try_get_cs_owned_object_js_handle_ref(root.address, 0);
if (js_handle) {
if (js_handle === JSHandleDisposed) {
throw new Error("Cannot access a disposed JSObject at " + root.value);
}
return mono_wasm_get_jsobj_from_js_handle(js_handle);
}
// otherwise this is C# only object
// get strong reference to Object
const gc_handle = wrapped_cs_functions._get_js_owned_object_gc_handle_ref(root.address);
// see if we have js owned instance for this gc_handle already
let result = _lookup_js_owned_object(gc_handle);
// If the JS object for this gc_handle was already collected (or was never created)
if (is_nullish(result)) {
result = new ManagedObject();
// keep the gc_handle so that we could easily convert it back to original C# object for roundtrip
result[js_owned_gc_handle_symbol] = gc_handle;
setup_managed_proxy(result, gc_handle);
}
return result;
}
// Licensed to the .NET Foundation under one or more agreements.
const primitiveConverters = new Map();
const _signature_converters = new Map();
function _get_type_name(typePtr) {
if (!typePtr)
return "<null>";
return wrapped_c_functions.mono_wasm_get_type_name(typePtr);
}
function _get_type_aqn(typePtr) {
if (!typePtr)
return "<null>";
return wrapped_c_functions.mono_wasm_get_type_aqn(typePtr);
}
function _get_class_name(classPtr) {
if (!classPtr)
return "<null>";
return wrapped_c_functions.mono_wasm_get_type_name(wrapped_c_functions.mono_wasm_class_get_type(classPtr));
}
function find_method(klass, name, n) {
return wrapped_c_functions.mono_wasm_assembly_find_method(klass, name, n);
}
function get_method(method_name) {
const res = find_method(runtimeHelpers.runtime_interop_exports_class, method_name, -1);
if (!res)
throw "Can't find method " + runtimeHelpers.runtime_interop_namespace + "." + runtimeHelpers.runtime_interop_exports_classname + ":" + method_name;
return res;
}
function bind_runtime_method(method_name, signature) {
const method = get_method(method_name);
return mono_bind_method(method, null, signature, "BINDINGS_" + method_name);
}
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
function _create_named_function(name, argumentNames, body, closure) {
let result = null;
let closureArgumentList = null;
let closureArgumentNames = null;
if (closure) {
closureArgumentNames = Object.keys(closure);
closureArgumentList = new Array(closureArgumentNames.length);
for (let i = 0, l = closureArgumentNames.length; i < l; i++)
closureArgumentList[i] = closure[closureArgumentNames[i]];
}
const constructor = _create_rebindable_named_function(name, argumentNames, body, closureArgumentNames);
// eslint-disable-next-line prefer-spread
result = constructor.apply(null, closureArgumentList);
return result;
}
function _create_rebindable_named_function(name, argumentNames, body, closureArgNames) {
const strictPrefix = "\"use strict\";\r\n";
let uriPrefix = "", escapedFunctionIdentifier = "";
if (name) {
uriPrefix = "//# sourceURL=https://mono-wasm.invalid/" + name + "\r\n";
escapedFunctionIdentifier = name;
}
else {
escapedFunctionIdentifier = "unnamed";
}
let rawFunctionText = "function " + escapedFunctionIdentifier + "(" +
argumentNames.join(", ") +
") {\r\n" +
body +
"\r\n};\r\n";
const lineBreakRE = /\r(\n?)/g;
rawFunctionText =
uriPrefix + strictPrefix +
rawFunctionText.replace(lineBreakRE, "\r\n ") +
` return ${escapedFunctionIdentifier};\r\n`;
let result = null, keys = null;
if (closureArgNames) {
keys = closureArgNames.concat([rawFunctionText]);
}
else {
keys = [rawFunctionText];
}
result = Function.apply(Function, keys);
return result;
}
function _create_primitive_converters() {
const result = primitiveConverters;
result.set("m", { steps: [{}], size: 0 });
result.set("s", { steps: [{ convert_root: js_string_to_mono_string_root.bind(BINDING$1) }], size: 0, needs_root: true });
result.set("S", { steps: [{ convert_root: js_string_to_mono_string_interned_root.bind(BINDING$1) }], size: 0, needs_root: true });
// note we also bind first argument to false for both _js_to_mono_obj and _js_to_mono_uri,
// because we will root the reference, so we don't need in-flight reference
// also as those are callback arguments and we don't have platform code which would release the in-flight reference on C# end
result.set("o", { steps: [{ convert_root: js_to_mono_obj_root.bind(BINDING$1) }], size: 0, needs_root: true });
result.set("u", { steps: [{ convert_root: _js_to_mono_uri_root.bind(BINDING$1, false) }], size: 0, needs_root: true });
// ref object aka T&&
result.set("R", { steps: [{ convert_root: js_to_mono_obj_root.bind(BINDING$1), byref: true }], size: 0, needs_root: true });
// result.set ('k', { steps: [{ convert: js_to_mono_enum.bind (this), indirect: 'i64'}], size: 8});
result.set("j", { steps: [{ convert: js_to_mono_enum.bind(BINDING$1), indirect: "i32" }], size: 8 });
result.set("b", { steps: [{ indirect: "bool" }], size: 8 });
result.set("i", { steps: [{ indirect: "i32" }], size: 8 });
result.set("I", { steps: [{ indirect: "u32" }], size: 8 });
result.set("l", { steps: [{ indirect: "i52" }], size: 8 });
result.set("L", { steps: [{ indirect: "u52" }], size: 8 });
result.set("f", { steps: [{ indirect: "float" }], size: 8 });
result.set("d", { steps: [{ indirect: "double" }], size: 8 });
}
function _create_converter_for_marshal_string(args_marshal /*ArgsMarshalString*/) {
const steps = [];
let size = 0;
let is_result_definitely_unmarshaled = false, is_result_possibly_unmarshaled = false, result_unmarshaled_if_argc = -1, needs_root_buffer = false;
for (let i = 0; i < args_marshal.length; ++i) {
const key = args_marshal[i];
if (i === args_marshal.length - 1) {
if (key === "!") {
is_result_definitely_unmarshaled = true;
continue;
}
else if (key === "m") {
is_result_possibly_unmarshaled = true;
result_unmarshaled_if_argc = args_marshal.length - 1;
}
}
else if (key === "!")
throw new Error("! must be at the end of the signature");
const conv = primitiveConverters.get(key);
if (!conv)
throw new Error("Unknown parameter type " + key);
const localStep = Object.create(conv.steps[0]);
localStep.size = conv.size;
if (conv.needs_root)
needs_root_buffer = true;
localStep.needs_root = conv.needs_root;
localStep.key = key;
steps.push(localStep);
size += conv.size;
}
return {
steps, size, args_marshal,
is_result_definitely_unmarshaled,
is_result_possibly_unmarshaled,
result_unmarshaled_if_argc,
needs_root_buffer
};
}
function _get_converter_for_marshal_string(args_marshal /*ArgsMarshalString*/) {
let converter = _signature_converters.get(args_marshal);
if (!converter) {
converter = _create_converter_for_marshal_string(args_marshal);
_signature_converters.set(args_marshal, converter);
}
return converter;
}
function _compile_converter_for_marshal_string(args_marshal /*ArgsMarshalString*/) {
const converter = _get_converter_for_marshal_string(args_marshal);
if (typeof (converter.args_marshal) !== "string")
throw new Error("Corrupt converter for '" + args_marshal + "'");
if (converter.compiled_function && converter.compiled_variadic_function)
return converter;
const converterName = args_marshal.replace("!", "_result_unmarshaled");
converter.name = converterName;
let body = [];
let argumentNames = ["method"];
const closure = {
Module,
setI32,
setU32,
setF32,
setF64,
setU52,
setI52,
setB32,
setI32_unchecked,
setU32_unchecked,
scratchValueRoot: converter.scratchValueRoot,
stackAlloc: Module.stackAlloc,
_zero_region
};
let indirectLocalOffset = 0;
// ensure the indirect values are 8-byte aligned so that aligned loads and stores will work
const indirectBaseOffset = ((((args_marshal.length * 4) + 7) / 8) | 0) * 8;
// worst-case allocation size instead of allocating dynamically, plus padding
// the padding is necessary to ensure that we don't overrun the buffer due to
// the 8-byte alignment we did above
const bufferSizeBytes = converter.size + (args_marshal.length * 4) + 16;
body.push("if (!method) throw new Error('no method provided');", `const buffer = stackAlloc(${bufferSizeBytes});`, `_zero_region(buffer, ${bufferSizeBytes});`, `const indirectStart = buffer + ${indirectBaseOffset};`, "");
for (let i = 0; i < converter.steps.length; i++) {
const step = converter.steps[i];
const closureKey = "step" + i;
const valueKey = "value" + i;
const argKey = "arg" + i;
const offsetText = `(indirectStart + ${indirectLocalOffset})`;
argumentNames.push(argKey);
if (step.convert_root) {
if (!(!step.indirect)) throw new Error("Assert failed: converter step cannot both be rooted and indirect"); // inlined mono_assert
if (!converter.scratchValueRoot) {
// HACK: new_external_root rightly won't accept a null address
const dummyAddress = Module.stackSave();
converter.scratchValueRoot = mono_wasm_new_external_root(dummyAddress);
closure.scratchValueRoot = converter.scratchValueRoot;
}
closure[closureKey] = step.convert_root;
// Update our scratch external root to point to the indirect slot where our
// managed pointer is destined to live
body.push(`scratchValueRoot._set_address(${offsetText});`);
// Convert the object and store the managed reference through our scratch external root
body.push(`${closureKey}(${argKey}, scratchValueRoot);`);
if (step.byref) {
// for T&& we pass the address of the pointer stored on the stack
body.push(`let ${valueKey} = ${offsetText};`);
}
else {
// It is safe to pass the pointer by value now since we know it is pinned
body.push(`let ${valueKey} = scratchValueRoot.value;`);
}
}
else if (step.convert) {
closure[closureKey] = step.convert;
body.push(`let ${valueKey} = ${closureKey}(${argKey}, method, ${i});`);
}
else {
body.push(`let ${valueKey} = ${argKey};`);
}
if (step.needs_root && !step.convert_root) {
body.push("if (!rootBuffer) throw new Error('no root buffer provided');");
body.push(`rootBuffer.set (${i}, ${valueKey});`);
}
if (step.indirect) {
switch (step.indirect) {
case "bool":
body.push(`setB32(${offsetText}, ${valueKey});`);
break;
case "u32":
body.push(`setU32(${offsetText}, ${valueKey});`);
break;
case "i32":
body.push(`setI32(${offsetText}, ${valueKey});`);
break;
case "float":
body.push(`setF32(${offsetText}, ${valueKey});`);
break;
case "double":
body.push(`setF64(${offsetText}, ${valueKey});`);
break;
case "i52":
body.push(`setI52(${offsetText}, ${valueKey});`);
break;
case "u52":
body.push(`setU52(${offsetText}, ${valueKey});`);
break;
default:
throw new Error("Unimplemented indirect type: " + step.indirect);
}
body.push(`setU32_unchecked(buffer + (${i} * 4), ${offsetText});`);
indirectLocalOffset += step.size;
}
else {
body.push(`setU32_unchecked(buffer + (${i} * 4), ${valueKey});`);
indirectLocalOffset += 4;
}
body.push("");
}
body.push("return buffer;");
let bodyJs = body.join("\r\n"), compiledFunction = null, compiledVariadicFunction = null;
try {
compiledFunction = _create_named_function("converter_" + converterName, argumentNames, bodyJs, closure);
converter.compiled_function = compiledFunction;
}
catch (exc) {
converter.compiled_function = null;
console.warn("MONO_WASM: compiling converter failed for", bodyJs, "with error", exc);
throw exc;
}
argumentNames = ["method", "args"];
const variadicClosure = {
converter: compiledFunction
};
body = [
"return converter(",
" method,"
];
for (let i = 0; i < converter.steps.length; i++) {
body.push(" args[" + i +
((i == converter.steps.length - 1)
? "]"
: "], "));
}
body.push(");");
bodyJs = body.join("\r\n");
try {
compiledVariadicFunction = _create_named_function("variadic_converter_" + converterName, argumentNames, bodyJs, variadicClosure);
converter.compiled_variadic_function = compiledVariadicFunction;
}
catch (exc) {
converter.compiled_variadic_function = null;
console.warn("MONO_WASM: compiling converter failed for", bodyJs, "with error", exc);
throw exc;
}
converter.scratchRootBuffer = null;
converter.scratchBuffer = VoidPtrNull;
return converter;
}
function _maybe_produce_signature_warning(converter) {
if (converter.has_warned_about_signature)
return;
console.warn("MONO_WASM: Deprecated raw return value signature: '" + converter.args_marshal + "'. End the signature with '!' instead of 'm'.");
converter.has_warned_about_signature = true;
}
function _decide_if_result_is_marshaled(converter, argc) {
if (!converter)
return true;
if (converter.is_result_possibly_unmarshaled &&
(argc === converter.result_unmarshaled_if_argc)) {
if (argc < converter.result_unmarshaled_if_argc)
throw new Error(`Expected >= ${converter.result_unmarshaled_if_argc} argument(s) but got ${argc} for signature '${converter.args_marshal}'`);
_maybe_produce_signature_warning(converter);
return false;
}
else {
if (argc < converter.steps.length)
throw new Error(`Expected ${converter.steps.length} argument(s) but got ${argc} for signature '${converter.args_marshal}'`);
return !converter.is_result_definitely_unmarshaled;
}
}
function mono_bind_method(method, this_arg, args_marshal /*ArgsMarshalString*/, friendly_name) {
if (typeof (args_marshal) !== "string")
throw new Error("args_marshal argument invalid, expected string");
let converter = null;
if (typeof (args_marshal) === "string") {
converter = _compile_converter_for_marshal_string(args_marshal);
}
// FIXME
const unbox_buffer_size = 128;
const unbox_buffer = Module._malloc(unbox_buffer_size);
const token = {
friendlyName: friendly_name,
method,
converter,
scratchRootBuffer: null,
scratchBuffer: VoidPtrNull,
scratchResultRoot: mono_wasm_new_root(),
scratchExceptionRoot: mono_wasm_new_root()
};
const closure = {
Module,
mono_wasm_new_root,
_create_temp_frame,
_handle_exception_for_call,
_teardown_after_call,
mono_wasm_try_unbox_primitive_and_get_type_ref: wrap_c_function("mono_wasm_try_unbox_primitive_and_get_type_ref"),
_unbox_mono_obj_root_with_known_nonprimitive_type,
invoke_method_ref: wrap_c_function("mono_wasm_invoke_method_ref"),
method,
token,
unbox_buffer,
unbox_buffer_size,
getB32,
getI32,
getU32,
getF32,
getF64,
stackSave: Module.stackSave
};
const converterKey = converter ? "converter_" + converter.name : "";
if (converter)
closure[converterKey] = converter;
const argumentNames = [];
const body = [
"_create_temp_frame();",
"let resultRoot = token.scratchResultRoot, exceptionRoot = token.scratchExceptionRoot, sp = stackSave();",
"token.scratchResultRoot = null;",
"token.scratchExceptionRoot = null;",
"if (resultRoot === null)",
" resultRoot = mono_wasm_new_root ();",
"if (exceptionRoot === null)",
" exceptionRoot = mono_wasm_new_root ();",
""
];
if (converter) {
body.push(`let buffer = ${converterKey}.compiled_function(`, " method,");
for (let i = 0; i < converter.steps.length; i++) {
const argName = "arg" + i;
argumentNames.push(argName);
body.push(" " + argName +
((i == converter.steps.length - 1)
? ""
: ", "));
}
body.push(");");
}
else {
body.push("let buffer = 0;");
}
if (converter && converter.is_result_definitely_unmarshaled) {
body.push("let is_result_marshaled = false;");
}
else if (converter && converter.is_result_possibly_unmarshaled) {
body.push(`let is_result_marshaled = arguments.length !== ${converter.result_unmarshaled_if_argc};`);
}
else {
body.push("let is_result_marshaled = true;");
}
// We inline a bunch of the invoke and marshaling logic here in order to eliminate the GC pressure normally
// created by the unboxing part of the call process. Because unbox_mono_obj(_root) can return non-numeric
// types, v8 and spidermonkey allocate and store its result on the heap (in the nursery, to be fair).
// For a bound method however, we know the result will always be the same type because C# methods have known
// return types. Inlining the invoke and marshaling logic means that even though the bound method has logic
// for handling various types, only one path through the method (for its appropriate return type) will ever
// be taken, and the JIT will see that the 'result' local and thus the return value of this function are
// always of the exact same type. All of the branches related to this end up being predicted and low-cost.
// The end result is that bound method invocations don't always allocate, so no more nursery GCs. Yay! -kg
body.push("", "invoke_method_ref (method, 0, buffer, exceptionRoot.address, resultRoot.address);", `_handle_exception_for_call (${converterKey}, token, buffer, resultRoot, exceptionRoot, sp);`, "", "let resultPtr = resultRoot.value, result = undefined;");
if (converter) {
if (converter.is_result_possibly_unmarshaled)
body.push("if (!is_result_marshaled) ");
if (converter.is_result_definitely_unmarshaled || converter.is_result_possibly_unmarshaled)
body.push(" result = resultPtr;");
if (!converter.is_result_definitely_unmarshaled)
body.push("if (is_result_marshaled) {",
// For the common scenario where the return type is a primitive, we want to try and unbox it directly
// into our existing heap allocation and then read it out of the heap. Doing this all in one operation
// means that we only need to enter a gc safe region twice (instead of 3+ times with the normal,
// slower check-type-and-then-unbox flow which has extra checks since unbox verifies the type).
" let resultType = mono_wasm_try_unbox_primitive_and_get_type_ref (resultRoot.address, unbox_buffer, unbox_buffer_size);", " switch (resultType) {", ` case ${1 /* MarshalType.INT */}:`, " result = getI32(unbox_buffer); break;", ` case ${32 /* MarshalType.POINTER */}:`, // FIXME: Is this right?
` case ${25 /* MarshalType.UINT32 */}:`, " result = getU32(unbox_buffer); break;", ` case ${24 /* MarshalType.FP32 */}:`, " result = getF32(unbox_buffer); break;", ` case ${2 /* MarshalType.FP64 */}:`, " result = getF64(unbox_buffer); break;", ` case ${8 /* MarshalType.BOOL */}:`, " result = getB32(unbox_buffer); break;", ` case ${28 /* MarshalType.CHAR */}:`, " result = String.fromCharCode(getI32(unbox_buffer)); break;", ` case ${0 /* MarshalType.NULL */}:`, " result = null; break;", " default:", " result = _unbox_mono_obj_root_with_known_nonprimitive_type (resultRoot, resultType, unbox_buffer); break;", " }", "}");
}
else {
throw new Error("No converter");
}
if (friendly_name) {
const escapeRE = /[^A-Za-z0-9_$]/g;
friendly_name = friendly_name.replace(escapeRE, "_");
}
let displayName = friendly_name || ("clr_" + method);
if (this_arg)
displayName += "_this" + this_arg;
body.push(`_teardown_after_call (${converterKey}, token, buffer, resultRoot, exceptionRoot, sp);`, "return result;");
const bodyJs = body.join("\r\n");
const result = _create_named_function(displayName, argumentNames, bodyJs, closure);
return result;
}
const _assembly_cache_by_name = new Map();
const _class_cache_by_assembly = new Map();
let _corlib = MonoAssemblyNull;
function assembly_load(name) {
if (_assembly_cache_by_name.has(name))
return _assembly_cache_by_name.get(name);
const result = wrapped_c_functions.mono_wasm_assembly_load(name);
_assembly_cache_by_name.set(name, result);
return result;
}
function _find_cached_class(assembly, namespace, name) {
let namespaces = _class_cache_by_assembly.get(assembly);
if (!namespaces)
_class_cache_by_assembly.set(assembly, namespaces = new Map());
let classes = namespaces.get(namespace);
if (!classes) {
classes = new Map();
namespaces.set(namespace, classes);
}
return classes.get(name);
}
function _set_cached_class(assembly, namespace, name, ptr) {
const namespaces = _class_cache_by_assembly.get(assembly);
if (!namespaces)
throw new Error("internal error");
const classes = namespaces.get(namespace);
if (!classes)
throw new Error("internal error");
classes.set(name, ptr);
}
function find_corlib_class(namespace, name, throw_on_failure) {
if (!_corlib)
_corlib = wrapped_c_functions.mono_wasm_get_corlib();
let result = _find_cached_class(_corlib, namespace, name);
if (result !== undefined)
return result;
result = wrapped_c_functions.mono_wasm_assembly_find_class(_corlib, namespace, name);
if (throw_on_failure && !result)
throw new Error(`Failed to find corlib class ${namespace}.${name}`);
_set_cached_class(_corlib, namespace, name, result);
return result;
}
function find_class_in_assembly(assembly_name, namespace, name, throw_on_failure) {
const assembly = assembly_load(assembly_name);
let result = _find_cached_class(assembly, namespace, name);
if (result !== undefined)
return result;
result = wrapped_c_functions.mono_wasm_assembly_find_class(assembly, namespace, name);
if (throw_on_failure && !result)
throw new Error(`Failed to find class ${namespace}.${name} in ${assembly_name}`);
_set_cached_class(assembly, namespace, name, result);
return result;
}
function find_corlib_type(namespace, name, throw_on_failure) {
const classPtr = find_corlib_class(namespace, name, throw_on_failure);
if (!classPtr)
return MonoTypeNull;
return wrapped_c_functions.mono_wasm_class_get_type(classPtr);
}
function find_type_in_assembly(assembly_name, namespace, name, throw_on_failure) {
const classPtr = find_class_in_assembly(assembly_name, namespace, name, throw_on_failure);
if (!classPtr)
return MonoTypeNull;
return wrapped_c_functions.mono_wasm_class_get_type(classPtr);
}
// Licensed to the .NET Foundation under one or more agreements.
function _verify_args_for_method_call(args_marshal /*ArgsMarshalString*/, args) {
const has_args = args && (typeof args === "object") && args.length > 0;
const has_args_marshal = typeof args_marshal === "string";
if (has_args) {
if (!has_args_marshal)
throw new Error("No signature provided for method call.");
else if (args.length > args_marshal.length)
throw new Error("Too many parameter values. Expected at most " + args_marshal.length + " value(s) for signature " + args_marshal);
}
return has_args_marshal && has_args;
}
function _convert_exception_for_method_call(result, exception) {
if (exception.value === MonoObjectNull)
return null;
const msg = conv_string_root(result);
const err = new Error(msg); //the convention is that invoke_method ToString () any outgoing exception
// console.warn (`error ${msg} at location ${err.stack});
return err;
}
/*
args_marshal is a string with one character per parameter that tells how to marshal it, here are the valid values:
i: int32
j: int32 - Enum with underlying type of int32
l: int64
k: int64 - Enum with underlying type of int64
f: float
d: double
s: string
S: interned string
o: js object will be converted to a C# object (this will box numbers/bool/promises)
m: raw mono object. Don't use it unless you know what you're doing
to suppress marshaling of the return value, place '!' at the end of args_marshal, i.e. 'ii!' instead of 'ii'
*/
function call_method_ref(method, this_arg, args_marshal /*ArgsMarshalString*/, args) {
// HACK: Sometimes callers pass null or undefined, coerce it to 0 since that's what wasm expects
let this_arg_ref = undefined;
if (typeof (this_arg) === "number")
this_arg_ref = this_arg;
else if (typeof (this_arg) === "object")
this_arg_ref = this_arg.address;
else
this_arg_ref = coerceNull(this_arg);
// Detect someone accidentally passing the wrong type of value to method
if (typeof method !== "number")
throw new Error(`method must be an address in the native heap, but was '${method}'`);
if (!method)
throw new Error("no method specified");
if (typeof (this_arg_ref) !== "number")
throw new Error(`this_arg must be a root instance, the address of a root, or undefined, but was ${this_arg}`);
const needs_converter = _verify_args_for_method_call(args_marshal, args);
let buffer = VoidPtrNull, converter = undefined;
const sp = Module.stackSave();
let is_result_marshaled = true;
// TODO: Only do this if the signature needs marshaling
_create_temp_frame();
// check if the method signature needs argument mashalling
if (needs_converter) {
converter = _compile_converter_for_marshal_string(args_marshal);
is_result_marshaled = _decide_if_result_is_marshaled(converter, args.length);
buffer = converter.compiled_variadic_function(method, args);
}
return _call_method_with_converted_args(method, this_arg_ref, converter, null, buffer, is_result_marshaled, sp);
}
function _handle_exception_for_call(converter, token, buffer, resultRoot, exceptionRoot, sp) {
const exc = _convert_exception_for_method_call(resultRoot, exceptionRoot);
if (!exc)
return;
_teardown_after_call(converter, token, buffer, resultRoot, exceptionRoot, sp);
throw exc;
}
function _handle_exception_and_produce_result_for_call(converter, token, buffer, resultRoot, exceptionRoot, sp, is_result_marshaled) {
_handle_exception_for_call(converter, token, buffer, resultRoot, exceptionRoot, sp);
let result;
if (is_result_marshaled)
result = unbox_mono_obj_root(resultRoot);
else
result = resultRoot.value;
_teardown_after_call(converter, token, buffer, resultRoot, exceptionRoot, sp);
return result;
}
function _teardown_after_call(converter, token, buffer, resultRoot, exceptionRoot, sp) {
_release_temp_frame();
Module.stackRestore(sp);
if (typeof (resultRoot) === "object") {
resultRoot.clear();
if ((token !== null) && (token.scratchResultRoot === null))
token.scratchResultRoot = resultRoot;
else
resultRoot.release();
}
if (typeof (exceptionRoot) === "object") {
exceptionRoot.clear();
if ((token !== null) && (token.scratchExceptionRoot === null))
token.scratchExceptionRoot = exceptionRoot;
else
exceptionRoot.release();
}
}
function _call_method_with_converted_args(method, this_arg_ref, converter, token, buffer, is_result_marshaled, sp) {
const resultRoot = mono_wasm_new_root(), exceptionRoot = mono_wasm_new_root();
wrapped_c_functions.mono_wasm_invoke_method_ref(method, this_arg_ref, buffer, exceptionRoot.address, resultRoot.address);
return _handle_exception_and_produce_result_for_call(converter, token, buffer, resultRoot, exceptionRoot, sp, is_result_marshaled);
}
function call_static_method(fqn, args, signature /*ArgsMarshalString*/) {
if (!(runtimeHelpers.mono_wasm_bindings_is_ready)) throw new Error("Assert failed: Expected binding to be initialized later during startup sequence."); // inlined mono_assert
const method = mono_method_resolve(fqn);
if (typeof signature === "undefined")
signature = mono_method_get_call_signature_ref(method, undefined);
return call_method_ref(method, undefined, signature, args);
}
function mono_bind_static_method(fqn, signature /*ArgsMarshalString*/) {
if (!(runtimeHelpers.mono_wasm_bindings_is_ready)) throw new Error("Assert failed: Expected binding to be initialized later during startup sequence."); // inlined mono_assert
const method = mono_method_resolve(fqn);
if (typeof signature === "undefined")
signature = mono_method_get_call_signature_ref(method, undefined);
return mono_bind_method(method, null, signature, fqn);
}
function mono_bind_assembly_entry_point(assembly, signature /*ArgsMarshalString*/) {
if (!(runtimeHelpers.mono_wasm_bindings_is_ready)) throw new Error("Assert failed: Expected binding to be initialized later during startup sequence."); // inlined mono_assert
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 = wrapped_c_functions.mono_wasm_assembly_get_entry_point(asm, auto_set_breakpoint);
if (!method)
throw new Error("Could not find entry point for assembly: " + assembly);
if (typeof (signature) !== "string")
signature = mono_method_get_call_signature_ref(method, undefined);
return async function (...args) {
if (args.length > 0 && Array.isArray(args[0]))
args[0] = js_array_to_mono_array(args[0], true, false);
return call_method_ref(method, undefined, signature, args);
};
}
function mono_call_assembly_entry_point(assembly, args, signature /*ArgsMarshalString*/) {
if (!(runtimeHelpers.mono_wasm_bindings_is_ready)) throw new Error("Assert failed: Expected binding to be initialized later during startup sequence."); // inlined mono_assert
if (!args) {
args = [[]];
}
return mono_bind_assembly_entry_point(assembly, signature)(...args);
}
function mono_wasm_invoke_js_with_args_ref(js_handle, method_name, args, is_exception, result_address) {
const argsRoot = mono_wasm_new_external_root(args), nameRoot = mono_wasm_new_external_root(method_name), resultRoot = mono_wasm_new_external_root(result_address);
try {
const js_name = conv_string_root(nameRoot);
if (!js_name || (typeof (js_name) !== "string")) {
wrap_error_root(is_exception, "ERR12: Invalid method name object @" + nameRoot.value, resultRoot);
return;
}
const obj = get_js_obj(js_handle);
if (is_nullish(obj)) {
wrap_error_root(is_exception, "ERR13: Invalid JS object handle '" + js_handle + "' while invoking '" + js_name + "'", resultRoot);
return;
}
const js_args = mono_array_root_to_js_array(argsRoot);
try {
const m = obj[js_name];
if (typeof m === "undefined")
throw new Error("Method: '" + js_name + "' not found for: '" + Object.prototype.toString.call(obj) + "'");
const res = m.apply(obj, js_args);
js_to_mono_obj_root(res, resultRoot, true);
}
catch (ex) {
wrap_error_root(is_exception, ex, resultRoot);
}
}
finally {
argsRoot.release();
nameRoot.release();
resultRoot.release();
}
}
function mono_wasm_get_object_property_ref(js_handle, property_name, is_exception, result_address) {
const nameRoot = mono_wasm_new_external_root(property_name), resultRoot = mono_wasm_new_external_root(result_address);
try {
const js_name = conv_string_root(nameRoot);
if (!js_name) {
wrap_error_root(is_exception, "Invalid property name object '" + nameRoot.value + "'", resultRoot);
return;
}
const obj = mono_wasm_get_jsobj_from_js_handle(js_handle);
if (is_nullish(obj)) {
wrap_error_root(is_exception, "ERR01: Invalid JS object handle '" + js_handle + "' while geting '" + js_name + "'", resultRoot);
return;
}
const m = obj[js_name];
js_to_mono_obj_root(m, resultRoot, true);
}
catch (ex) {
wrap_error_root(is_exception, ex, resultRoot);
}
finally {
resultRoot.release();
nameRoot.release();
}
}
function mono_wasm_set_object_property_ref(js_handle, property_name, value, createIfNotExist, hasOwnProperty, is_exception, result_address) {
const valueRoot = mono_wasm_new_external_root(value), nameRoot = mono_wasm_new_external_root(property_name), resultRoot = mono_wasm_new_external_root(result_address);
try {
const property = conv_string_root(nameRoot);
if (!property) {
wrap_error_root(is_exception, "Invalid property name object '" + property_name + "'", resultRoot);
return;
}
const js_obj = mono_wasm_get_jsobj_from_js_handle(js_handle);
if (is_nullish(js_obj)) {
wrap_error_root(is_exception, "ERR02: Invalid JS object handle '" + js_handle + "' while setting '" + property + "'", resultRoot);
return;
}
let result = false;
const js_value = unbox_mono_obj_root(valueRoot);
if (createIfNotExist) {
js_obj[property] = js_value;
result = true;
}
else {
result = false;
if (!createIfNotExist) {
if (!Object.prototype.hasOwnProperty.call(js_obj, property)) {
js_to_mono_obj_root(false, resultRoot, false);
return;
}
}
if (hasOwnProperty === true) {
if (Object.prototype.hasOwnProperty.call(js_obj, property)) {
js_obj[property] = js_value;
result = true;
}
}
else {
js_obj[property] = js_value;
result = true;
}
}
js_to_mono_obj_root(result, resultRoot, false);
}
catch (ex) {
wrap_error_root(is_exception, ex, resultRoot);
}
finally {
resultRoot.release();
nameRoot.release();
valueRoot.release();
}
}
function mono_wasm_get_by_index_ref(js_handle, property_index, is_exception, result_address) {
const resultRoot = mono_wasm_new_external_root(result_address);
try {
const obj = mono_wasm_get_jsobj_from_js_handle(js_handle);
if (is_nullish(obj)) {
wrap_error_root(is_exception, "ERR03: Invalid JS object handle '" + js_handle + "' while getting [" + property_index + "]", resultRoot);
return;
}
const m = obj[property_index];
js_to_mono_obj_root(m, resultRoot, true);
}
catch (ex) {
wrap_error_root(is_exception, ex, resultRoot);
}
finally {
resultRoot.release();
}
}
function mono_wasm_set_by_index_ref(js_handle, property_index, value, is_exception, result_address) {
const valueRoot = mono_wasm_new_external_root(value), resultRoot = mono_wasm_new_external_root(result_address);
try {
const obj = mono_wasm_get_jsobj_from_js_handle(js_handle);
if (is_nullish(obj)) {
wrap_error_root(is_exception, "ERR04: Invalid JS object handle '" + js_handle + "' while setting [" + property_index + "]", resultRoot);
return;
}
const js_value = unbox_mono_obj_root(valueRoot);
obj[property_index] = js_value;
resultRoot.clear();
}
catch (ex) {
wrap_error_root(is_exception, ex, resultRoot);
}
finally {
resultRoot.release();
valueRoot.release();
}
}
function mono_wasm_get_global_object_ref(global_name, is_exception, result_address) {
const nameRoot = mono_wasm_new_external_root(global_name), resultRoot = mono_wasm_new_external_root(result_address);
try {
const js_name = conv_string_root(nameRoot);
let globalObj;
if (!js_name) {
globalObj = globalThis;
}
else if (js_name == "Module") {
globalObj = Module;
}
else if (js_name == "INTERNAL") {
globalObj = INTERNAL$1;
}
else {
globalObj = globalThis[js_name];
}
// TODO returning null may be useful when probing for browser features
if (globalObj === null || typeof globalObj === undefined) {
wrap_error_root(is_exception, "Global object '" + js_name + "' not found.", resultRoot);
return;
}
js_to_mono_obj_root(globalObj, resultRoot, true);
}
catch (ex) {
wrap_error_root(is_exception, ex, resultRoot);
}
finally {
resultRoot.release();
nameRoot.release();
}
}
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
function _wrap_error_flag(is_exception, ex) {
let res = "unknown exception";
if (ex) {
res = ex.toString();
const stack = ex.stack;
if (stack) {
// Some JS runtimes insert the error message at the top of the stack, some don't,
// so normalize it by using the stack as the result if it already contains the error
if (stack.startsWith(res))
res = stack;
else
res += "\n" + stack;
}
res = INTERNAL$1.mono_wasm_symbolicate_string(res);
}
if (is_exception) {
Module.setValue(is_exception, 1, "i32");
}
return res;
}
/**
* @deprecated Not GC or thread safe
*/
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
function wrap_error(is_exception, ex) {
const res = _wrap_error_flag(is_exception, ex);
return js_string_to_mono_string(res);
}
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
function wrap_error_root(is_exception, ex, result) {
const res = _wrap_error_flag(is_exception, ex);
js_string_to_mono_string_root(res, result);
}
function mono_method_get_call_signature_ref(method, mono_obj) {
return call_method_ref(runtimeHelpers.get_call_sig_ref, undefined, "im", [method, mono_obj ? mono_obj.address : runtimeHelpers._null_root.address]);
}
function parseFQN(fqn) {
const assembly = fqn.substring(fqn.indexOf("[") + 1, fqn.indexOf("]")).trim();
fqn = fqn.substring(fqn.indexOf("]") + 1).trim();
const methodname = fqn.substring(fqn.indexOf(":") + 1);
fqn = fqn.substring(0, fqn.indexOf(":")).trim();
let namespace = "";
let classname = fqn;
if (fqn.indexOf(".") != -1) {
const idx = fqn.lastIndexOf(".");
namespace = fqn.substring(0, idx);
classname = fqn.substring(idx + 1);
}
if (!assembly.trim())
throw new Error("No assembly name specified " + fqn);
if (!classname.trim())
throw new Error("No class name specified " + fqn);
if (!methodname.trim())
throw new Error("No method name specified " + fqn);
return { assembly, namespace, classname, methodname };
}
function mono_method_resolve(fqn) {
const { assembly, namespace, classname, methodname } = parseFQN(fqn);
const asm = wrapped_c_functions.mono_wasm_assembly_load(assembly);
if (!asm)
throw new Error("Could not find assembly: " + assembly);
const klass = wrapped_c_functions.mono_wasm_assembly_find_class(asm, namespace, classname);
if (!klass)
throw new Error("Could not find class: " + namespace + ":" + classname + " in assembly " + assembly);
const method = find_method(klass, methodname, -1);
if (!method)
throw new Error("Could not find method: " + methodname);
return method;
}
// Blazor specific custom routine
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
function mono_wasm_invoke_js_blazor(exceptionMessage, callInfo, arg0, arg1, arg2) {
try {
const blazorExports = globalThis.Blazor;
if (!blazorExports) {
throw new Error("The blazor.webassembly.js library is not loaded.");
}
return blazorExports._internal.invokeJSFromDotNet(callInfo, arg0, arg1, arg2);
}
catch (ex) {
const exceptionJsString = ex.message + "\n" + ex.stack;
const exceptionRoot = mono_wasm_new_root();
js_string_to_mono_string_root(exceptionJsString, exceptionRoot);
exceptionRoot.copy_to_address(exceptionMessage);
exceptionRoot.release();
return 0;
}
}
// Licensed to the .NET Foundation under one or more agreements.
// Creates a new typed array from pinned array address from pinned_array allocated on the heap to the typed array.
// address of managed pinned array -> copy from heap -> typed array memory
function typed_array_from(pinned_array, begin, end, bytes_per_element, type) {
// typed array
let newTypedArray = null;
switch (type) {
case 5:
newTypedArray = new Int8Array(end - begin);
break;
case 6:
newTypedArray = new Uint8Array(end - begin);
break;
case 7:
newTypedArray = new Int16Array(end - begin);
break;
case 8:
newTypedArray = new Uint16Array(end - begin);
break;
case 9:
newTypedArray = new Int32Array(end - begin);
break;
case 10:
newTypedArray = new Uint32Array(end - begin);
break;
case 13:
newTypedArray = new Float32Array(end - begin);
break;
case 14:
newTypedArray = new Float64Array(end - begin);
break;
case 15: // This is a special case because the typed array is also byte[]
newTypedArray = new Uint8ClampedArray(end - begin);
break;
default:
throw new Error("Unknown array type " + type);
}
typedarray_copy_from(newTypedArray, pinned_array, begin, end, bytes_per_element);
return newTypedArray;
}
// Copy the existing typed array to the heap pointed to by the pinned array address
// typed array memory -> copy to heap -> address of managed pinned array
function typedarray_copy_to(typed_array, pinned_array, begin, end, bytes_per_element) {
// JavaScript typed arrays are array-like objects and provide a mechanism for accessing
// raw binary data. (...) To achieve maximum flexibility and efficiency, JavaScript typed arrays
// split the implementation into buffers and views. A buffer (implemented by the ArrayBuffer object)
// is an object representing a chunk of data; it has no format to speak of, and offers no
// mechanism for accessing its contents. In order to access the memory contained in a buffer,
// you need to use a view. A view provides a context - that is, a data type, starting offset,
// and number of elements - that turns the data into an actual typed array.
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Typed_arrays
if (has_backing_array_buffer(typed_array) && typed_array.BYTES_PER_ELEMENT) {
// Some sanity checks of what is being asked of us
// lets play it safe and throw an error here instead of assuming to much.
// Better safe than sorry later
if (bytes_per_element !== typed_array.BYTES_PER_ELEMENT)
throw new Error("Inconsistent element sizes: TypedArray.BYTES_PER_ELEMENT '" + typed_array.BYTES_PER_ELEMENT + "' sizeof managed element: '" + bytes_per_element + "'");
// how much space we have to work with
let num_of_bytes = (end - begin) * bytes_per_element;
// how much typed buffer space are we talking about
const view_bytes = typed_array.length * typed_array.BYTES_PER_ELEMENT;
// only use what is needed.
if (num_of_bytes > view_bytes)
num_of_bytes = view_bytes;
// offset index into the view
const offset = begin * bytes_per_element;
// Create a view over the heap pointed to by the pinned array address
const heapBytes = new Uint8Array(Module.HEAPU8.buffer, pinned_array + offset, num_of_bytes);
// Copy the bytes of the typed array to the heap.
heapBytes.set(new Uint8Array(typed_array.buffer, typed_array.byteOffset, num_of_bytes));
return num_of_bytes;
}
else {
throw new Error("Object '" + typed_array + "' is not a typed array");
}
}
// Copy the pinned array address from pinned_array allocated on the heap to the typed array.
// address of managed pinned array -> copy from heap -> typed array memory
function typedarray_copy_from(typed_array, pinned_array, begin, end, bytes_per_element) {
// JavaScript typed arrays are array-like objects and provide a mechanism for accessing
// raw binary data. (...) To achieve maximum flexibility and efficiency, JavaScript typed arrays
// split the implementation into buffers and views. A buffer (implemented by the ArrayBuffer object)
// is an object representing a chunk of data; it has no format to speak of, and offers no
// mechanism for accessing its contents. In order to access the memory contained in a buffer,
// you need to use a view. A view provides a context - that is, a data type, starting offset,
// and number of elements - that turns the data into an actual typed array.
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Typed_arrays
if (has_backing_array_buffer(typed_array) && typed_array.BYTES_PER_ELEMENT) {
// Some sanity checks of what is being asked of us
// lets play it safe and throw an error here instead of assuming to much.
// Better safe than sorry later
if (bytes_per_element !== typed_array.BYTES_PER_ELEMENT)
throw new Error("Inconsistent element sizes: TypedArray.BYTES_PER_ELEMENT '" + typed_array.BYTES_PER_ELEMENT + "' sizeof managed element: '" + bytes_per_element + "'");
// how much space we have to work with
let num_of_bytes = (end - begin) * bytes_per_element;
// how much typed buffer space are we talking about
const view_bytes = typed_array.length * typed_array.BYTES_PER_ELEMENT;
// only use what is needed.
if (num_of_bytes > view_bytes)
num_of_bytes = view_bytes;
// Create a new view for mapping
const typedarrayBytes = new Uint8Array(typed_array.buffer, 0, num_of_bytes);
// offset index into the view
const offset = begin * bytes_per_element;
// Set view bytes to value from HEAPU8
typedarrayBytes.set(Module.HEAPU8.subarray(pinned_array + offset, pinned_array + offset + num_of_bytes));
return num_of_bytes;
}
else {
throw new Error("Object '" + typed_array + "' is not a typed array");
}
}
function mono_wasm_typed_array_copy_to_ref(js_handle, pinned_array, begin, end, bytes_per_element, is_exception, result_address) {
const resultRoot = mono_wasm_new_external_root(result_address);
try {
const js_obj = mono_wasm_get_jsobj_from_js_handle(js_handle);
if (is_nullish(js_obj)) {
wrap_error_root(is_exception, "ERR07: Invalid JS object handle '" + js_handle + "'", resultRoot);
return;
}
const res = typedarray_copy_to(js_obj, pinned_array, begin, end, bytes_per_element);
// FIXME: We should just return an int
// returns num_of_bytes boxed
js_to_mono_obj_root(res, resultRoot, false);
}
catch (exc) {
wrap_error_root(is_exception, String(exc), resultRoot);
}
finally {
resultRoot.release();
}
}
// eslint-disable-next-line @typescript-eslint/no-unused-vars
function mono_wasm_typed_array_from_ref(pinned_array, begin, end, bytes_per_element, type, is_exception, result_address) {
const resultRoot = mono_wasm_new_external_root(result_address);
try {
const res = typed_array_from(pinned_array, begin, end, bytes_per_element, type);
// returns JS typed array like Int8Array, to be wraped with JSObject proxy
js_to_mono_obj_root(res, resultRoot, true);
}
catch (exc) {
wrap_error_root(is_exception, String(exc), resultRoot);
}
finally {
resultRoot.release();
}
}
function mono_wasm_typed_array_copy_from_ref(js_handle, pinned_array, begin, end, bytes_per_element, is_exception, result_address) {
const resultRoot = mono_wasm_new_external_root(result_address);
try {
const js_obj = mono_wasm_get_jsobj_from_js_handle(js_handle);
if (is_nullish(js_obj)) {
wrap_error_root(is_exception, "ERR08: Invalid JS object handle '" + js_handle + "'", resultRoot);
return;
}
const res = typedarray_copy_from(js_obj, pinned_array, begin, end, bytes_per_element);
// FIXME: We should just return an int
// returns num_of_bytes boxed
js_to_mono_obj_root(res, resultRoot, false);
}
catch (exc) {
wrap_error_root(is_exception, String(exc), resultRoot);
}
finally {
resultRoot.release();
}
}
function has_backing_array_buffer(js_obj) {
return typeof SharedArrayBuffer !== "undefined"
? js_obj.buffer instanceof ArrayBuffer || js_obj.buffer instanceof SharedArrayBuffer
: js_obj.buffer instanceof ArrayBuffer;
}
// @bytes must be a typed array. space is allocated for it in the native heap
// and it is copied to that location. returns the address of the allocation.
function mono_wasm_load_bytes_into_heap(bytes) {
const memoryOffset = Module._malloc(bytes.length);
const heapBytes = new Uint8Array(Module.HEAPU8.buffer, memoryOffset, bytes.length);
heapBytes.set(bytes);
return memoryOffset;
}
async function mono_run_main_and_exit(main_assembly_name, args) {
try {
const result = await mono_run_main(main_assembly_name, args);
set_exit_code(result);
}
catch (error) {
if (error instanceof runtimeHelpers.ExitStatus) {
return;
}
set_exit_code(1, error);
}
}
async function mono_run_main(main_assembly_name, args) {
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"));
}
return mono_call_assembly_entry_point(main_assembly_name, [args], "m");
}
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
function mono_on_abort(error) {
abort_startup(error, false);
set_exit_code(1, error);
}
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
function set_exit_code(exit_code, reason) {
if (reason && !(reason instanceof runtimeHelpers.ExitStatus)) {
if (reason instanceof Error)
Module.printErr(INTERNAL$1.mono_wasm_stringify_as_error_with_stack(reason));
else if (typeof reason == "string")
Module.printErr(reason);
else
Module.printErr(JSON.stringify(reason));
}
else {
reason = new runtimeHelpers.ExitStatus(exit_code);
}
runtimeHelpers.quit(exit_code, reason);
}
// Licensed to the .NET Foundation under one or more agreements.
function initialize_marshalers_to_js() {
if (cs_to_js_marshalers.size == 0) {
cs_to_js_marshalers.set(MarshalerType.Array, _marshal_array_to_js);
cs_to_js_marshalers.set(MarshalerType.Span, _marshal_span_to_js);
cs_to_js_marshalers.set(MarshalerType.ArraySegment, _marshal_array_segment_to_js);
cs_to_js_marshalers.set(MarshalerType.Boolean, _marshal_bool_to_js);
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.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);
cs_to_js_marshalers.set(MarshalerType.IntPtr, _marshal_intptr_to_js);
cs_to_js_marshalers.set(MarshalerType.Double, _marshal_double_to_js);
cs_to_js_marshalers.set(MarshalerType.String, _marshal_string_to_js);
cs_to_js_marshalers.set(MarshalerType.Exception, marshal_exception_to_js);
cs_to_js_marshalers.set(MarshalerType.JSException, marshal_exception_to_js);
cs_to_js_marshalers.set(MarshalerType.JSObject, _marshal_js_object_to_js);
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.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);
cs_to_js_marshalers.set(MarshalerType.Void, _marshal_null_to_js);
cs_to_js_marshalers.set(MarshalerType.Discard, _marshal_null_to_js);
}
}
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
function generate_arg_marshal_to_js(sig, index, arg_offset, sig_offset, jsname, closure) {
let converters = "";
let converter_types = "";
let call_body = "";
const converter_name = "converter" + index;
let converter_name_arg1 = "null";
let converter_name_arg2 = "null";
let converter_name_arg3 = "null";
let converter_name_res = "null";
let marshaler_type = get_signature_type(sig);
if (marshaler_type === MarshalerType.None || marshaler_type === MarshalerType.Void) {
return {
converters,
call_body,
marshaler_type
};
}
const marshaler_type_res = get_signature_res_type(sig);
if (marshaler_type_res !== MarshalerType.None) {
const converter = cs_to_js_marshalers.get(marshaler_type_res);
if (!(converter && typeof converter === "function")) throw new Error(`Assert failed: Unknow converter for type ${marshaler_type_res} at ${index}`); // inlined mono_assert
if (marshaler_type != MarshalerType.Nullable) {
converter_name_res = "converter" + index + "_res";
converters += ", " + converter_name_res;
converter_types += " " + MarshalerType[marshaler_type_res];
closure[converter_name_res] = converter;
}
else {
marshaler_type = marshaler_type_res;
}
}
const marshaler_type_arg1 = get_signature_arg1_type(sig);
if (marshaler_type_arg1 !== MarshalerType.None) {
const converter = js_to_cs_marshalers.get(marshaler_type_arg1);
if (!(converter && typeof converter === "function")) throw new Error(`Assert failed: Unknow converter for type ${marshaler_type_arg1} at ${index}`); // inlined mono_assert
converter_name_arg1 = "converter" + index + "_arg1";
converters += ", " + converter_name_arg1;
converter_types += " " + MarshalerType[marshaler_type_arg1];
closure[converter_name_arg1] = converter;
}
const marshaler_type_arg2 = get_signature_arg2_type(sig);
if (marshaler_type_arg2 !== MarshalerType.None) {
const converter = js_to_cs_marshalers.get(marshaler_type_arg2);
if (!(converter && typeof converter === "function")) throw new Error(`Assert failed: Unknow converter for type ${marshaler_type_arg2} at ${index}`); // inlined mono_assert
converter_name_arg2 = "converter" + index + "_arg2";
converters += ", " + converter_name_arg2;
converter_types += " " + MarshalerType[marshaler_type_arg2];
closure[converter_name_arg2] = converter;
}
const marshaler_type_arg3 = get_signature_arg3_type(sig);
if (marshaler_type_arg3 !== MarshalerType.None) {
const converter = js_to_cs_marshalers.get(marshaler_type_arg3);
if (!(converter && typeof converter === "function")) throw new Error(`Assert failed: Unknow converter for type ${marshaler_type_arg3} at ${index}`); // inlined mono_assert
converter_name_arg3 = "converter" + index + "_arg3";
converters += ", " + converter_name_arg3;
converter_types += " " + MarshalerType[marshaler_type_arg3];
closure[converter_name_arg3] = converter;
}
const converter = cs_to_js_marshalers.get(marshaler_type);
if (!(converter && typeof converter === "function")) throw new Error(`Assert failed: Unknow converter for type ${marshaler_type} at ${index} `); // inlined mono_assert
converters += ", " + converter_name;
converter_types += " " + MarshalerType[marshaler_type];
closure[converter_name] = converter;
if (marshaler_type == MarshalerType.Task) {
call_body = ` const ${jsname} = ${converter_name}(args + ${arg_offset}, signature + ${sig_offset}, ${converter_name_res}); // ${converter_types} \n`;
}
else if (marshaler_type == MarshalerType.Action || marshaler_type == MarshalerType.Function) {
call_body = ` const ${jsname} = ${converter_name}(args + ${arg_offset}, signature + ${sig_offset}, ${converter_name_res}, ${converter_name_arg1}, ${converter_name_arg2}, ${converter_name_arg3}); // ${converter_types} \n`;
}
else {
call_body = ` const ${jsname} = ${converter_name}(args + ${arg_offset}, signature + ${sig_offset}); // ${converter_types} \n`;
}
return {
converters,
call_body,
marshaler_type
};
}
function _marshal_bool_to_js(arg) {
const type = get_arg_type(arg);
if (type == MarshalerType.None) {
return null;
}
return get_arg_b8(arg);
}
function _marshal_byte_to_js(arg) {
const type = get_arg_type(arg);
if (type == MarshalerType.None) {
return null;
}
return get_arg_u8(arg);
}
function _marshal_char_to_js(arg) {
const type = get_arg_type(arg);
if (type == MarshalerType.None) {
return null;
}
return get_arg_u16(arg);
}
function _marshal_int16_to_js(arg) {
const type = get_arg_type(arg);
if (type == MarshalerType.None) {
return null;
}
return get_arg_i16(arg);
}
function _marshal_int32_to_js(arg) {
const type = get_arg_type(arg);
if (type == MarshalerType.None) {
return null;
}
return get_arg_i32(arg);
}
function _marshal_int52_to_js(arg) {
const type = get_arg_type(arg);
if (type == MarshalerType.None) {
return null;
}
return get_arg_i52(arg);
}
function _marshal_bigint64_to_js(arg) {
const type = get_arg_type(arg);
if (type == MarshalerType.None) {
return null;
}
return get_arg_i64_big(arg);
}
function _marshal_float_to_js(arg) {
const type = get_arg_type(arg);
if (type == MarshalerType.None) {
return null;
}
return get_arg_f32(arg);
}
function _marshal_double_to_js(arg) {
const type = get_arg_type(arg);
if (type == MarshalerType.None) {
return null;
}
return get_arg_f64(arg);
}
function _marshal_intptr_to_js(arg) {
const type = get_arg_type(arg);
if (type == MarshalerType.None) {
return null;
}
return get_arg_intptr(arg);
}
function _marshal_null_to_js() {
return null;
}
function _marshal_datetime_to_js(arg) {
const type = get_arg_type(arg);
if (type === MarshalerType.None) {
return null;
}
return get_arg_date(arg);
}
function _marshal_delegate_to_js(arg, _, res_converter, arg1_converter, arg2_converter, arg3_converter) {
const type = get_arg_type(arg);
if (type === MarshalerType.None) {
return null;
}
const anyModule = Module;
const gc_handle = get_arg_gc_handle(arg);
let result = _lookup_js_owned_object(gc_handle);
if (result === null || result === undefined) {
// this will create new Function for the C# delegate
result = (arg1_js, arg2_js, arg3_js) => {
const sp = anyModule.stackSave();
try {
const args = anyModule.stackAlloc(JavaScriptMarshalerArgSize * 5);
const exc = get_arg(args, 0);
set_arg_type(exc, MarshalerType.None);
const res = get_arg(args, 1);
set_arg_type(res, MarshalerType.None);
set_gc_handle(res, gc_handle);
const arg1 = get_arg(args, 2);
const arg2 = get_arg(args, 3);
const arg3 = get_arg(args, 4);
if (arg1_converter) {
arg1_converter(arg1, arg1_js);
}
if (arg2_converter) {
arg2_converter(arg2, arg2_js);
}
if (arg3_converter) {
arg3_converter(arg3, arg3_js);
}
const fail = wrapped_c_functions.mono_wasm_invoke_method_bound(runtimeHelpers.call_delegate, args);
if (fail)
throw new Error("ERR23: Unexpected error: " + conv_string(fail));
if (is_args_exception(args))
throw marshal_exception_to_js(exc);
if (res_converter) {
return res_converter(res);
}
}
finally {
anyModule.stackRestore(sp);
}
};
setup_managed_proxy(result, gc_handle);
}
return result;
}
function _marshal_task_to_js(arg, _, res_converter) {
const type = get_arg_type(arg);
if (type === MarshalerType.None) {
return null;
}
if (type !== MarshalerType.Task) {
if (!res_converter) {
// when we arrived here from _marshal_cs_object_to_js
res_converter = cs_to_js_marshalers.get(type);
}
if (!(res_converter)) throw new Error(`Assert failed: Unknow sub_converter for type ${MarshalerType[type]} `); // inlined mono_assert
// this is already resolved
const val = res_converter(arg);
return new Promise((resolve) => resolve(val));
}
const js_handle = get_arg_js_handle(arg);
// console.log("_marshal_task_to_js A" + js_handle);
if (js_handle == JSHandleNull) {
// this is already resolved void
return new Promise((resolve) => resolve(undefined));
}
const promise = mono_wasm_get_jsobj_from_js_handle(js_handle);
if (!(!!promise)) throw new Error(`Assert failed: ERR28: promise not found for js_handle: ${js_handle} `); // inlined mono_assert
assertIsControllablePromise(promise);
const promise_control = getPromiseController(promise);
const orig_resolve = promise_control.resolve;
promise_control.resolve = (argInner) => {
// console.log("_marshal_task_to_js R" + js_handle);
const type = get_arg_type(argInner);
if (type === MarshalerType.None) {
orig_resolve(null);
return;
}
if (!res_converter) {
// when we arrived here from _marshal_cs_object_to_js
res_converter = cs_to_js_marshalers.get(type);
}
if (!(res_converter)) throw new Error(`Assert failed: Unknow sub_converter for type ${MarshalerType[type]}`); // inlined mono_assert
const js_value = res_converter(argInner);
orig_resolve(js_value);
};
return promise;
}
function mono_wasm_marshal_promise(args) {
const exc = get_arg(args, 0);
const res = get_arg(args, 1);
const arg_handle = get_arg(args, 2);
const arg_value = get_arg(args, 3);
const exc_type = get_arg_type(exc);
const value_type = get_arg_type(arg_value);
const js_handle = get_arg_js_handle(arg_handle);
if (js_handle === JSHandleNull) {
const { promise, promise_control } = createPromiseController();
const js_handle = mono_wasm_get_js_handle(promise);
set_js_handle(res, js_handle);
if (exc_type !== MarshalerType.None) {
// this is already failed task
const reason = marshal_exception_to_js(exc);
promise_control.reject(reason);
}
else if (value_type !== MarshalerType.Task) {
// this is already resolved task
const sub_converter = cs_to_js_marshalers.get(value_type);
if (!(sub_converter)) throw new Error(`Assert failed: Unknow sub_converter for type ${MarshalerType[value_type]} `); // inlined mono_assert
const data = sub_converter(arg_value);
promise_control.resolve(data);
}
}
else {
// resolve existing promise
const promise = mono_wasm_get_jsobj_from_js_handle(js_handle);
if (!(!!promise)) throw new Error(`Assert failed: ERR25: promise not found for js_handle: ${js_handle} `); // inlined mono_assert
assertIsControllablePromise(promise);
const promise_control = getPromiseController(promise);
if (exc_type !== MarshalerType.None) {
const reason = marshal_exception_to_js(exc);
promise_control.reject(reason);
}
else if (value_type !== MarshalerType.Task) {
// here we assume that resolve was wrapped with sub_converter inside _marshal_task_to_js
promise_control.resolve(arg_value);
}
}
set_arg_type(res, MarshalerType.Task);
set_arg_type(exc, MarshalerType.None);
}
function _marshal_string_to_js(arg) {
const type = get_arg_type(arg);
if (type == MarshalerType.None) {
return null;
}
const root = get_string_root(arg);
try {
const value = conv_string_root(root);
return value;
}
finally {
root.release();
}
}
function marshal_exception_to_js(arg) {
const type = get_arg_type(arg);
if (type == MarshalerType.None) {
return null;
}
if (type == MarshalerType.JSException) {
// this is JSException roundtrip
const js_handle = get_arg_js_handle(arg);
const js_obj = mono_wasm_get_jsobj_from_js_handle(js_handle);
return js_obj;
}
const gc_handle = get_arg_gc_handle(arg);
let result = _lookup_js_owned_object(gc_handle);
if (result === null || result === undefined) {
// this will create new ManagedError
const message = _marshal_string_to_js(arg);
result = new ManagedError(message);
setup_managed_proxy(result, gc_handle);
}
return result;
}
function _marshal_js_object_to_js(arg) {
const type = get_arg_type(arg);
if (type == MarshalerType.None) {
return null;
}
const js_handle = get_arg_js_handle(arg);
const js_obj = mono_wasm_get_jsobj_from_js_handle(js_handle);
return js_obj;
}
function _marshal_cs_object_to_js(arg) {
const marshaler_type = get_arg_type(arg);
if (marshaler_type == MarshalerType.None) {
return null;
}
if (marshaler_type == MarshalerType.JSObject) {
const js_handle = get_arg_js_handle(arg);
const js_obj = mono_wasm_get_jsobj_from_js_handle(js_handle);
return js_obj;
}
if (marshaler_type == MarshalerType.Array) {
const element_type = get_arg_element_type(arg);
return _marshal_array_to_js_impl(arg, element_type);
}
if (marshaler_type == MarshalerType.Object) {
const gc_handle = get_arg_gc_handle(arg);
if (gc_handle === GCHandleNull) {
return null;
}
// see if we have js owned instance for this gc_handle already
let result = _lookup_js_owned_object(gc_handle);
// If the JS object for this gc_handle was already collected (or was never created)
if (!result) {
result = new ManagedObject();
setup_managed_proxy(result, gc_handle);
}
return result;
}
// other types
const converter = cs_to_js_marshalers.get(marshaler_type);
if (!(converter)) throw new Error(`Assert failed: Unknow converter for type ${MarshalerType[marshaler_type]}`); // inlined mono_assert
return converter(arg);
}
function _marshal_array_to_js(arg, sig) {
if (!(!!sig)) throw new Error("Assert failed: Expected valid sig parameter"); // inlined mono_assert
const element_type = get_signature_arg1_type(sig);
return _marshal_array_to_js_impl(arg, element_type);
}
function _marshal_array_to_js_impl(arg, element_type) {
const type = get_arg_type(arg);
if (type == MarshalerType.None) {
return null;
}
const elementSize = array_element_size(element_type);
if (!(elementSize != -1)) throw new Error(`Assert failed: Element type ${MarshalerType[element_type]} not supported`); // inlined mono_assert
const buffer_ptr = get_arg_intptr(arg);
const length = get_arg_length(arg);
let result = null;
if (element_type == MarshalerType.String) {
result = new Array(length);
for (let index = 0; index < length; index++) {
const element_arg = get_arg(buffer_ptr, index);
result[index] = _marshal_string_to_js(element_arg);
}
wrapped_c_functions.mono_wasm_deregister_root(buffer_ptr);
}
else if (element_type == MarshalerType.Object) {
result = new Array(length);
for (let index = 0; index < length; index++) {
const element_arg = get_arg(buffer_ptr, index);
result[index] = _marshal_cs_object_to_js(element_arg);
}
wrapped_c_functions.mono_wasm_deregister_root(buffer_ptr);
}
else if (element_type == MarshalerType.JSObject) {
result = new Array(length);
for (let index = 0; index < length; index++) {
const element_arg = get_arg(buffer_ptr, index);
result[index] = _marshal_js_object_to_js(element_arg);
}
}
else if (element_type == MarshalerType.Byte) {
const sourceView = Module.HEAPU8.subarray(buffer_ptr, buffer_ptr + length);
result = sourceView.slice(); //copy
}
else if (element_type == MarshalerType.Int32) {
const sourceView = Module.HEAP32.subarray(buffer_ptr >> 2, (buffer_ptr >> 2) + length);
result = sourceView.slice(); //copy
}
else if (element_type == MarshalerType.Double) {
const sourceView = Module.HEAPF64.subarray(buffer_ptr >> 3, (buffer_ptr >> 3) + length);
result = sourceView.slice(); //copy
}
else {
throw new Error(`NotImplementedException ${MarshalerType[element_type]} `);
}
Module._free(buffer_ptr);
return result;
}
function _marshal_span_to_js(arg, sig) {
if (!(!!sig)) throw new Error("Assert failed: Expected valid sig parameter"); // inlined mono_assert
const element_type = get_signature_arg1_type(sig);
const buffer_ptr = get_arg_intptr(arg);
const length = get_arg_length(arg);
let result = null;
if (element_type == MarshalerType.Byte) {
result = new Span(buffer_ptr, length, 0 /* MemoryViewType.Byte */);
}
else if (element_type == MarshalerType.Int32) {
result = new Span(buffer_ptr, length, 1 /* MemoryViewType.Int32 */);
}
else if (element_type == MarshalerType.Double) {
result = new Span(buffer_ptr, length, 2 /* MemoryViewType.Double */);
}
else {
throw new Error(`NotImplementedException ${MarshalerType[element_type]} `);
}
return result;
}
function _marshal_array_segment_to_js(arg, sig) {
if (!(!!sig)) throw new Error("Assert failed: Expected valid sig parameter"); // inlined mono_assert
const element_type = get_signature_arg1_type(sig);
const buffer_ptr = get_arg_intptr(arg);
const length = get_arg_length(arg);
let result = null;
if (element_type == MarshalerType.Byte) {
result = new ArraySegment(buffer_ptr, length, 0 /* MemoryViewType.Byte */);
}
else if (element_type == MarshalerType.Int32) {
result = new ArraySegment(buffer_ptr, length, 1 /* MemoryViewType.Int32 */);
}
else if (element_type == MarshalerType.Double) {
result = new ArraySegment(buffer_ptr, length, 2 /* MemoryViewType.Double */);
}
else {
throw new Error(`NotImplementedException ${MarshalerType[element_type]} `);
}
const gc_handle = get_arg_gc_handle(arg);
setup_managed_proxy(result, gc_handle);
return result;
}
// Licensed to the .NET Foundation under one or more agreements.
function initialize_marshalers_to_cs() {
if (js_to_cs_marshalers.size == 0) {
js_to_cs_marshalers.set(MarshalerType.Array, _marshal_array_to_cs);
js_to_cs_marshalers.set(MarshalerType.Span, _marshal_span_to_cs);
js_to_cs_marshalers.set(MarshalerType.ArraySegment, _marshal_array_segment_to_cs);
js_to_cs_marshalers.set(MarshalerType.Boolean, _marshal_bool_to_cs);
js_to_cs_marshalers.set(MarshalerType.Byte, _marshal_byte_to_cs);
js_to_cs_marshalers.set(MarshalerType.Char, _marshal_char_to_cs);
js_to_cs_marshalers.set(MarshalerType.Int16, _marshal_int16_to_cs);
js_to_cs_marshalers.set(MarshalerType.Int32, _marshal_int32_to_cs);
js_to_cs_marshalers.set(MarshalerType.Int52, _marshal_int52_to_cs);
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.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);
js_to_cs_marshalers.set(MarshalerType.Exception, marshal_exception_to_cs);
js_to_cs_marshalers.set(MarshalerType.JSException, marshal_exception_to_cs);
js_to_cs_marshalers.set(MarshalerType.JSObject, _marshal_js_object_to_cs);
js_to_cs_marshalers.set(MarshalerType.Object, _marshal_cs_object_to_cs);
js_to_cs_marshalers.set(MarshalerType.Task, _marshal_task_to_cs);
js_to_cs_marshalers.set(MarshalerType.Action, _marshal_function_to_cs);
js_to_cs_marshalers.set(MarshalerType.Function, _marshal_function_to_cs);
js_to_cs_marshalers.set(MarshalerType.None, _marshal_null_to_cs); // also void
js_to_cs_marshalers.set(MarshalerType.Discard, _marshal_null_to_cs); // also void
js_to_cs_marshalers.set(MarshalerType.Void, _marshal_null_to_cs); // also void
}
}
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
function generate_arg_marshal_to_cs(sig, index, arg_offset, sig_offset, jsname, closure) {
let converters = "";
let converter_types = "";
let call_body = "";
const converter_name = "converter" + index;
let converter_name_arg1 = "null";
let converter_name_arg2 = "null";
let converter_name_arg3 = "null";
let converter_name_res = "null";
let marshaler_type = get_signature_type(sig);
if (marshaler_type === MarshalerType.None || marshaler_type === MarshalerType.Void) {
return {
converters,
call_body,
marshaler_type
};
}
const marshaler_type_res = get_signature_res_type(sig);
if (marshaler_type_res !== MarshalerType.None) {
const converter = js_to_cs_marshalers.get(marshaler_type_res);
if (!(converter && typeof converter === "function")) throw new Error(`Assert failed: Unknow converter for type ${marshaler_type_res} at ${index}`); // inlined mono_assert
if (marshaler_type != MarshalerType.Nullable) {
converter_name_res = "converter" + index + "_res";
converters += ", " + converter_name_res;
converter_types += " " + MarshalerType[marshaler_type_res];
closure[converter_name_res] = converter;
}
else {
marshaler_type = marshaler_type_res;
}
}
const marshaler_type_arg1 = get_signature_arg1_type(sig);
if (marshaler_type_arg1 !== MarshalerType.None) {
const converter = cs_to_js_marshalers.get(marshaler_type_arg1);
if (!(converter && typeof converter === "function")) throw new Error(`Assert failed: Unknow converter for type ${marshaler_type_arg1} at ${index}`); // inlined mono_assert
converter_name_arg1 = "converter" + index + "_arg1";
converters += ", " + converter_name_arg1;
converter_types += " " + MarshalerType[marshaler_type_arg1];
closure[converter_name_arg1] = converter;
}
const marshaler_type_arg2 = get_signature_arg2_type(sig);
if (marshaler_type_arg2 !== MarshalerType.None) {
const converter = cs_to_js_marshalers.get(marshaler_type_arg2);
if (!(converter && typeof converter === "function")) throw new Error(`Assert failed: Unknow converter for type ${marshaler_type_arg2} at ${index}`); // inlined mono_assert
converter_name_arg2 = "converter" + index + "_arg2";
converters += ", " + converter_name_arg2;
converter_types += " " + MarshalerType[marshaler_type_arg2];
closure[converter_name_arg2] = converter;
}
const marshaler_type_arg3 = get_signature_arg3_type(sig);
if (marshaler_type_arg3 !== MarshalerType.None) {
const converter = cs_to_js_marshalers.get(marshaler_type_arg3);
if (!(converter && typeof converter === "function")) throw new Error(`Assert failed: Unknow converter for type ${marshaler_type_arg3} at ${index}`); // inlined mono_assert
converter_name_arg3 = "converter" + index + "_arg3";
converters += ", " + converter_name_arg3;
converter_types += " " + MarshalerType[marshaler_type_arg3];
closure[converter_name_arg3] = converter;
}
const converter = js_to_cs_marshalers.get(marshaler_type);
const arg_type_name = MarshalerType[marshaler_type];
if (!(converter && typeof converter === "function")) throw new Error(`Assert failed: Unknow converter for type ${arg_type_name} (${marshaler_type}) at ${index} `); // inlined mono_assert
converters += ", " + converter_name;
converter_types += " " + arg_type_name;
closure[converter_name] = converter;
if (marshaler_type == MarshalerType.Task) {
call_body = ` ${converter_name}(args + ${arg_offset}, ${jsname}, signature + ${sig_offset}, ${converter_name_res}); // ${converter_types} \n`;
}
else if (marshaler_type == MarshalerType.Action || marshaler_type == MarshalerType.Function) {
call_body = ` ${converter_name}(args + ${arg_offset}, ${jsname}, signature + ${sig_offset}, ${converter_name_res}, ${converter_name_arg1}, ${converter_name_arg2}, ${converter_name_arg2}); // ${converter_types} \n`;
}
else {
call_body = ` ${converter_name}(args + ${arg_offset}, ${jsname}, signature + ${sig_offset}); // ${converter_types} \n`;
}
return {
converters,
call_body,
marshaler_type
};
}
function _marshal_bool_to_cs(arg, value) {
if (value === null || value === undefined) {
set_arg_type(arg, MarshalerType.None);
}
else {
set_arg_type(arg, MarshalerType.Boolean);
set_arg_b8(arg, value);
}
}
function _marshal_byte_to_cs(arg, value) {
if (value === null || value === undefined) {
set_arg_type(arg, MarshalerType.None);
}
else {
set_arg_type(arg, MarshalerType.Byte);
set_arg_u8(arg, value);
}
}
function _marshal_char_to_cs(arg, value) {
if (value === null || value === undefined) {
set_arg_type(arg, MarshalerType.None);
}
else {
set_arg_type(arg, MarshalerType.Char);
set_arg_u16(arg, value);
}
}
function _marshal_int16_to_cs(arg, value) {
if (value === null || value === undefined) {
set_arg_type(arg, MarshalerType.None);
}
else {
set_arg_type(arg, MarshalerType.Int16);
set_arg_i16(arg, value);
}
}
function _marshal_int32_to_cs(arg, value) {
if (value === null || value === undefined) {
set_arg_type(arg, MarshalerType.None);
}
else {
set_arg_type(arg, MarshalerType.Int32);
set_arg_i32(arg, value);
}
}
function _marshal_int52_to_cs(arg, value) {
if (value === null || value === undefined) {
set_arg_type(arg, MarshalerType.None);
}
else {
set_arg_type(arg, MarshalerType.Int52);
set_arg_i52(arg, value);
}
}
function _marshal_bigint64_to_cs(arg, value) {
if (value === null || value === undefined) {
set_arg_type(arg, MarshalerType.None);
}
else {
set_arg_type(arg, MarshalerType.BigInt64);
set_arg_i64_big(arg, value);
}
}
function _marshal_double_to_cs(arg, value) {
if (value === null || value === undefined) {
set_arg_type(arg, MarshalerType.None);
}
else {
set_arg_type(arg, MarshalerType.Double);
set_arg_f64(arg, value);
}
}
function _marshal_float_to_cs(arg, value) {
if (value === null || value === undefined) {
set_arg_type(arg, MarshalerType.None);
}
else {
set_arg_type(arg, MarshalerType.Single);
set_arg_f32(arg, value);
}
}
function _marshal_intptr_to_cs(arg, value) {
if (value === null || value === undefined) {
set_arg_type(arg, MarshalerType.None);
}
else {
set_arg_type(arg, MarshalerType.IntPtr);
set_arg_intptr(arg, value);
}
}
function _marshal_date_time_to_cs(arg, value) {
if (value === null || value === undefined) {
set_arg_type(arg, MarshalerType.None);
}
else {
if (!(value instanceof Date)) throw new Error("Assert failed: Value is not a Date"); // inlined mono_assert
set_arg_type(arg, MarshalerType.DateTime);
set_arg_date(arg, value);
}
}
function _marshal_date_time_offset_to_cs(arg, value) {
if (value === null || value === undefined) {
set_arg_type(arg, MarshalerType.None);
}
else {
if (!(value instanceof Date)) throw new Error("Assert failed: Value is not a Date"); // inlined mono_assert
set_arg_type(arg, MarshalerType.DateTimeOffset);
set_arg_date(arg, value);
}
}
function _marshal_string_to_cs(arg, value) {
if (value === null || value === undefined) {
set_arg_type(arg, MarshalerType.None);
}
else {
set_arg_type(arg, MarshalerType.String);
if (!(typeof value === "string")) throw new Error("Assert failed: Value is not a String"); // inlined mono_assert
_marshal_string_to_cs_impl(arg, value);
}
}
function _marshal_string_to_cs_impl(arg, value) {
const root = get_string_root(arg);
try {
js_string_to_mono_string_root(value, root);
}
finally {
root.release();
}
}
function _marshal_null_to_cs(arg) {
set_arg_type(arg, MarshalerType.None);
}
function _marshal_function_to_cs(arg, value, _, res_converter, arg1_converter, arg2_converter, arg3_converter) {
if (value === null || value === undefined) {
set_arg_type(arg, MarshalerType.None);
return;
}
if (!(value && value instanceof Function)) throw new Error("Assert failed: Value is not a Function"); // inlined mono_assert
// TODO: we could try to cache value -> existing JSHandle
const marshal_function_to_cs_wrapper = (args) => {
const exc = get_arg(args, 0);
const res = get_arg(args, 1);
const arg1 = get_arg(args, 2);
const arg2 = get_arg(args, 3);
const arg3 = get_arg(args, 4);
try {
let arg1_js = undefined;
let arg2_js = undefined;
let arg3_js = undefined;
if (arg1_converter) {
arg1_js = arg1_converter(arg1);
}
if (arg2_converter) {
arg2_js = arg2_converter(arg2);
}
if (arg3_converter) {
arg3_js = arg3_converter(arg3);
}
const res_js = value(arg1_js, arg2_js, arg3_js);
if (res_converter) {
res_converter(res, res_js);
}
}
catch (ex) {
marshal_exception_to_cs(exc, ex);
}
};
marshal_function_to_cs_wrapper[bound_js_function_symbol] = true;
const bound_function_handle = mono_wasm_get_js_handle(marshal_function_to_cs_wrapper);
set_js_handle(arg, bound_function_handle);
set_arg_type(arg, MarshalerType.Function); //TODO or action ?
}
class TaskCallbackHolder {
constructor(promise) {
this.promise = promise;
}
dispose() {
teardown_managed_proxy(this, GCHandleNull);
}
get isDisposed() {
return this[js_owned_gc_handle_symbol] === GCHandleNull;
}
}
function _marshal_task_to_cs(arg, value, _, res_converter) {
if (value === null || value === undefined) {
set_arg_type(arg, MarshalerType.None);
return;
}
if (!(isThenable(value))) throw new Error("Assert failed: Value is not a Promise"); // inlined mono_assert
const anyModule = Module;
const gc_handle = wrapped_cs_functions._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 => {
const sp = anyModule.stackSave();
try {
const args = anyModule.stackAlloc(JavaScriptMarshalerArgSize * 3);
const exc = get_arg(args, 0);
set_arg_type(exc, MarshalerType.None);
const res = get_arg(args, 1);
set_arg_type(res, MarshalerType.None);
set_gc_handle(res, gc_handle);
const arg1 = get_arg(args, 2);
if (!res_converter) {
_marshal_cs_object_to_cs(arg1, data);
}
else {
res_converter(arg1, data);
}
const fail = wrapped_c_functions.mono_wasm_invoke_method_bound(runtimeHelpers.complete_task_method, args);
if (fail)
throw new Error("ERR22: Unexpected error: " + conv_string(fail));
if (is_args_exception(args))
throw marshal_exception_to_js(exc);
}
finally {
anyModule.stackRestore(sp);
}
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 => {
const sp = anyModule.stackSave();
try {
const args = anyModule.stackAlloc(JavaScriptMarshalerArgSize * 3);
const res = get_arg(args, 1);
set_arg_type(res, MarshalerType.None);
set_gc_handle(res, gc_handle);
const exc = get_arg(args, 0);
if (typeof reason === "string" || reason === null || reason === undefined) {
reason = new Error(reason || "");
}
marshal_exception_to_cs(exc, reason);
const fail = wrapped_c_functions.mono_wasm_invoke_method_bound(runtimeHelpers.complete_task_method, args);
if (fail)
throw new Error("ERR24: Unexpected error: " + conv_string(fail));
if (is_args_exception(args))
throw marshal_exception_to_js(exc);
}
finally {
anyModule.stackRestore(sp);
}
teardown_managed_proxy(holder, gc_handle); // this holds holder alive for finalizer, until the promise is freed
});
}
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
function marshal_exception_to_cs(arg, value) {
if (value === null || value === undefined) {
set_arg_type(arg, MarshalerType.None);
}
else if (value instanceof ManagedError) {
set_arg_type(arg, MarshalerType.Exception);
// this is managed exception round-trip
const gc_handle = assert_not_disposed(value);
set_gc_handle(arg, gc_handle);
}
else {
if (!(typeof value === "object" || typeof value === "string")) throw new Error(`Assert failed: Value is not an Error ${typeof value}`); // inlined mono_assert
set_arg_type(arg, MarshalerType.JSException);
const message = value.toString();
_marshal_string_to_cs_impl(arg, message);
const known_js_handle = value[cs_owned_js_handle_symbol];
if (known_js_handle) {
set_js_handle(arg, known_js_handle);
}
else {
const js_handle = mono_wasm_get_js_handle(value);
set_js_handle(arg, js_handle);
}
}
}
function _marshal_js_object_to_cs(arg, value) {
if (value === undefined || value === null) {
set_arg_type(arg, MarshalerType.None);
}
else {
// if value was ManagedObject, it would be double proxied, but the C# signature requires that
if (!(value[js_owned_gc_handle_symbol] === undefined)) throw new Error("Assert failed: JSObject proxy of ManagedObject proxy is not supported"); // inlined mono_assert
if (!(typeof value === "function" || typeof value === "object")) throw new Error(`Assert failed: JSObject proxy of ${typeof value} is not supported`); // inlined mono_assert
set_arg_type(arg, MarshalerType.JSObject);
const js_handle = mono_wasm_get_js_handle(value);
set_js_handle(arg, js_handle);
}
}
function _marshal_cs_object_to_cs(arg, value) {
if (value === undefined || value === null) {
set_arg_type(arg, MarshalerType.None);
}
else {
const gc_handle = value[js_owned_gc_handle_symbol];
const js_type = typeof (value);
if (gc_handle === undefined) {
if (js_type === "string" || js_type === "symbol") {
set_arg_type(arg, MarshalerType.String);
_marshal_string_to_cs_impl(arg, value);
}
else if (js_type === "number") {
set_arg_type(arg, MarshalerType.Double);
set_arg_f64(arg, value);
}
else if (js_type === "bigint") {
// we do it because not all bigint values could fit into Int64
throw new Error("NotImplementedException: bigint");
}
else if (js_type === "boolean") {
set_arg_type(arg, MarshalerType.Boolean);
set_arg_b8(arg, value);
}
else if (value instanceof Date) {
set_arg_type(arg, MarshalerType.DateTime);
set_arg_date(arg, value);
}
else if (value instanceof Error) {
set_arg_type(arg, MarshalerType.JSException);
const js_handle = mono_wasm_get_js_handle(value);
set_js_handle(arg, js_handle);
}
else if (value instanceof Uint8Array) {
_marshal_array_to_cs_impl(arg, value, MarshalerType.Byte);
}
else if (value instanceof Float64Array) {
_marshal_array_to_cs_impl(arg, value, MarshalerType.Double);
}
else if (value instanceof Int32Array) {
_marshal_array_to_cs_impl(arg, value, MarshalerType.Int32);
}
else if (Array.isArray(value)) {
_marshal_array_to_cs_impl(arg, value, MarshalerType.Object);
}
else if (value instanceof Int16Array
|| value instanceof Int8Array
|| value instanceof Uint8ClampedArray
|| value instanceof Uint16Array
|| value instanceof Uint32Array
|| value instanceof Float32Array) {
throw new Error("NotImplementedException: TypedArray");
}
else if (isThenable(value)) {
_marshal_task_to_cs(arg, value);
}
else if (value instanceof Span) {
throw new Error("NotImplementedException: Span");
}
else if (js_type == "object") {
const js_handle = mono_wasm_get_js_handle(value);
set_arg_type(arg, MarshalerType.JSObject);
set_js_handle(arg, js_handle);
}
else {
throw new Error(`JSObject proxy is not supported for ${js_type} ${value}`);
}
}
else {
assert_not_disposed(value);
if (value instanceof ArraySegment) {
throw new Error("NotImplementedException: ArraySegment");
}
else if (value instanceof ManagedError) {
set_arg_type(arg, MarshalerType.Exception);
set_gc_handle(arg, gc_handle);
}
else if (value instanceof ManagedObject) {
set_arg_type(arg, MarshalerType.Object);
set_gc_handle(arg, gc_handle);
}
else {
throw new Error("NotImplementedException " + js_type);
}
}
}
}
function _marshal_array_to_cs(arg, value, sig) {
if (!(!!sig)) throw new Error("Assert failed: Expected valid sig parameter"); // inlined mono_assert
const element_type = get_signature_arg1_type(sig);
_marshal_array_to_cs_impl(arg, value, element_type);
}
function _marshal_array_to_cs_impl(arg, value, element_type) {
if (value === null || value === undefined) {
set_arg_type(arg, MarshalerType.None);
}
else {
const element_size = array_element_size(element_type);
if (!(element_size != -1)) throw new Error(`Assert failed: Element type ${MarshalerType[element_type]} not supported`); // inlined mono_assert
const length = value.length;
const buffer_length = element_size * length;
const buffer_ptr = Module._malloc(buffer_length);
if (element_type == MarshalerType.String) {
if (!(Array.isArray(value))) throw new Error("Assert failed: Value is not an Array"); // inlined mono_assert
_zero_region(buffer_ptr, buffer_length);
wrapped_c_functions.mono_wasm_register_root(buffer_ptr, buffer_length, "marshal_array_to_cs");
for (let index = 0; index < length; index++) {
const element_arg = get_arg(buffer_ptr, index);
_marshal_string_to_cs(element_arg, value[index]);
}
}
else if (element_type == MarshalerType.Object) {
if (!(Array.isArray(value))) throw new Error("Assert failed: Value is not an Array"); // inlined mono_assert
_zero_region(buffer_ptr, buffer_length);
wrapped_c_functions.mono_wasm_register_root(buffer_ptr, buffer_length, "marshal_array_to_cs");
for (let index = 0; index < length; index++) {
const element_arg = get_arg(buffer_ptr, index);
_marshal_cs_object_to_cs(element_arg, value[index]);
}
}
else if (element_type == MarshalerType.JSObject) {
if (!(Array.isArray(value))) throw new Error("Assert failed: Value is not an Array"); // inlined mono_assert
_zero_region(buffer_ptr, buffer_length);
for (let index = 0; index < length; index++) {
const element_arg = get_arg(buffer_ptr, index);
_marshal_js_object_to_cs(element_arg, value[index]);
}
}
else if (element_type == MarshalerType.Byte) {
if (!(Array.isArray(value) || value instanceof Uint8Array)) throw new Error("Assert failed: Value is not an Array or Uint8Array"); // inlined mono_assert
const targetView = Module.HEAPU8.subarray(buffer_ptr, buffer_ptr + length);
targetView.set(value);
}
else if (element_type == MarshalerType.Int32) {
if (!(Array.isArray(value) || value instanceof Int32Array)) throw new Error("Assert failed: Value is not an Array or Int32Array"); // inlined mono_assert
const targetView = Module.HEAP32.subarray(buffer_ptr >> 2, (buffer_ptr >> 2) + length);
targetView.set(value);
}
else if (element_type == MarshalerType.Double) {
if (!(Array.isArray(value) || value instanceof Float64Array)) throw new Error("Assert failed: Value is not an Array or Float64Array"); // inlined mono_assert
const targetView = Module.HEAPF64.subarray(buffer_ptr >> 3, (buffer_ptr >> 3) + length);
targetView.set(value);
}
else {
throw new Error("not implemented");
}
set_arg_intptr(arg, buffer_ptr);
set_arg_type(arg, MarshalerType.Array);
set_arg_element_type(arg, element_type);
set_arg_length(arg, value.length);
}
}
function _marshal_span_to_cs(arg, value, sig) {
if (!(!!sig)) throw new Error("Assert failed: Expected valid sig parameter"); // inlined mono_assert
if (!(!value.isDisposed)) throw new Error("Assert failed: ObjectDisposedException"); // inlined mono_assert
checkViewType(sig, value._viewType);
set_arg_type(arg, MarshalerType.Span);
set_arg_intptr(arg, value._pointer);
set_arg_length(arg, value.length);
}
// this only supports round-trip
function _marshal_array_segment_to_cs(arg, value, sig) {
if (!(!!sig)) throw new Error("Assert failed: Expected valid sig parameter"); // inlined mono_assert
const gc_handle = assert_not_disposed(value);
if (!(gc_handle)) throw new Error("Assert failed: Only roundtrip of ArraySegment instance created by C#"); // inlined mono_assert
checkViewType(sig, value._viewType);
set_arg_type(arg, MarshalerType.ArraySegment);
set_arg_intptr(arg, value._pointer);
set_arg_length(arg, value.length);
set_gc_handle(arg, gc_handle);
}
function checkViewType(sig, viewType) {
const element_type = get_signature_arg1_type(sig);
if (element_type == MarshalerType.Byte) {
if (!(0 /* MemoryViewType.Byte */ == viewType)) throw new Error("Assert failed: Expected MemoryViewType.Byte"); // inlined mono_assert
}
else if (element_type == MarshalerType.Int32) {
if (!(1 /* MemoryViewType.Int32 */ == viewType)) throw new Error("Assert failed: Expected MemoryViewType.Int32"); // inlined mono_assert
}
else if (element_type == MarshalerType.Double) {
if (!(2 /* MemoryViewType.Double */ == viewType)) throw new Error("Assert failed: Expected MemoryViewType.Double"); // inlined mono_assert
}
else {
throw new Error(`NotImplementedException ${MarshalerType[element_type]} `);
}
}
// Licensed to the .NET Foundation under one or more agreements.
class OperationFailedError extends Error {
}
const ERR_ARGS = -1;
const ERR_WORKER_FAILED = -2;
const ERR_OP_FAILED = -3;
const ERR_UNKNOWN = -100;
let mono_wasm_crypto = null;
function dotnet_browser_can_use_subtle_crypto_impl() {
return mono_wasm_crypto === null ? 0 : 1;
}
function dotnet_browser_simple_digest_hash(ver, input_buffer, input_len, output_buffer, output_len) {
const msg = {
func: "digest",
type: ver,
data: Array.from(Module.HEAPU8.subarray(input_buffer, input_buffer + input_len))
};
return _send_simple_msg(msg, "DIGEST HASH", output_buffer, output_len);
}
function dotnet_browser_sign(hashAlgorithm, key_buffer, key_len, input_buffer, input_len, output_buffer, output_len) {
const msg = {
func: "sign",
type: hashAlgorithm,
key: Array.from(Module.HEAPU8.subarray(key_buffer, key_buffer + key_len)),
data: Array.from(Module.HEAPU8.subarray(input_buffer, input_buffer + input_len))
};
return _send_simple_msg(msg, "SIGN HASH", output_buffer, output_len);
}
const AesBlockSizeBytes = 16; // 128 bits
function dotnet_browser_encrypt_decrypt(isEncrypting, key_buffer, key_len, iv_buffer, iv_len, input_buffer, input_len, output_buffer, output_len) {
if (input_len <= 0 || input_len % AesBlockSizeBytes !== 0) {
throw "ENCRYPT DECRYPT: data was not a full block: " + input_len;
}
const msg = {
func: "encrypt_decrypt",
isEncrypting: isEncrypting,
key: Array.from(Module.HEAPU8.subarray(key_buffer, key_buffer + key_len)),
iv: Array.from(Module.HEAPU8.subarray(iv_buffer, iv_buffer + iv_len)),
data: Array.from(Module.HEAPU8.subarray(input_buffer, input_buffer + input_len))
};
const result = _send_msg_worker(msg);
if (typeof result === "number") {
return result;
}
if (result.length > output_len) {
console.error(`MONO_WASM_ENCRYPT_DECRYPT: Encrypt/Decrypt length exceeds output length: ${result.length} > ${output_len}`);
return ERR_ARGS;
}
Module.HEAPU8.set(result, output_buffer);
return result.length;
}
function dotnet_browser_derive_bits(password_buffer, password_len, salt_buffer, salt_len, iterations, hashAlgorithm, output_buffer, output_len) {
const msg = {
func: "derive_bits",
password: Array.from(Module.HEAPU8.subarray(password_buffer, password_buffer + password_len)),
salt: Array.from(Module.HEAPU8.subarray(salt_buffer, salt_buffer + salt_len)),
iterations: iterations,
hashAlgorithm: hashAlgorithm,
lengthInBytes: output_len
};
return _send_simple_msg(msg, "DERIVE BITS", output_buffer, output_len);
}
function _send_simple_msg(msg, prefix, output_buffer, output_len) {
const result = _send_msg_worker(msg);
if (typeof result === "number") {
return result;
}
if (result.length > output_len) {
console.error(`MONO_WASM_ENCRYPT_DECRYPT: ${prefix}: Result length exceeds output length: ${result.length} > ${output_len}`);
return ERR_ARGS;
}
Module.HEAPU8.set(result, output_buffer);
return 0;
}
function init_crypto() {
if (typeof globalThis.crypto !== "undefined" && typeof globalThis.crypto.subtle !== "undefined"
&& typeof SharedArrayBuffer !== "undefined"
&& typeof Worker !== "undefined") {
console.debug("MONO_WASM: Initializing Crypto WebWorker");
const chan = LibraryChannel.create(1024); // 1024 is the buffer size in char units.
const worker = new Worker("dotnet-crypto-worker.js");
mono_wasm_crypto = {
channel: chan,
worker: worker,
};
worker.postMessage({
comm_buf: chan.get_comm_buffer(),
msg_buf: chan.get_msg_buffer(),
msg_char_len: chan.get_msg_len()
});
worker.onerror = event => {
console.warn(`MONO_WASM: Error in Crypto WebWorker. Cryptography digest calls will fallback to managed implementation. Error: ${event.message}`);
mono_wasm_crypto = null;
};
}
}
function _send_msg_worker(msg) {
if (!(!!mono_wasm_crypto)) throw new Error("Assert failed: subtle crypto not initialized"); // inlined mono_assert
try {
const response = mono_wasm_crypto.channel.send_msg(JSON.stringify(msg));
const responseJson = JSON.parse(response);
if (responseJson.error !== undefined) {
console.error(`MONO_WASM_ENCRYPT_DECRYPT: Worker failed with: ${responseJson.error}`);
if (responseJson.error_type == "ArgumentsError")
return ERR_ARGS;
if (responseJson.error_type == "WorkerFailedError")
return ERR_WORKER_FAILED;
return ERR_UNKNOWN;
}
return responseJson.result;
}
catch (err) {
if (err instanceof Error && err.stack !== undefined)
console.error(`MONO_WASM_ENCRYPT_DECRYPT: ${err.stack}`);
else
console.error(`MONO_WASM_ENCRYPT_DECRYPT: _send_msg_worker failed: ${err}`);
return ERR_OP_FAILED;
}
}
class LibraryChannel {
constructor(msg_char_len) {
this.msg_char_len = msg_char_len;
const int_bytes = 4;
const comm_byte_len = int_bytes * (this.COMM_LAST_IDX + 1);
this.comm_buf = new SharedArrayBuffer(comm_byte_len);
// JavaScript character encoding is UTF-16.
const char_bytes = 2;
const msg_byte_len = char_bytes * this.msg_char_len;
this.msg_buf = new SharedArrayBuffer(msg_byte_len);
// Create the local arrays to use.
this.comm = new Int32Array(this.comm_buf);
this.msg = new Uint16Array(this.msg_buf);
}
// LOCK states
get LOCK_UNLOCKED() { return 0; } // 0 means the lock is unlocked
get LOCK_OWNED() { return 1; } // 1 means the LibraryChannel owns the lock
// Index constants for the communication buffer.
get STATE_IDX() { return 0; }
get MSG_SIZE_IDX() { return 1; }
get LOCK_IDX() { return 2; }
get COMM_LAST_IDX() { return this.LOCK_IDX; }
// Communication states.
get STATE_SHUTDOWN() { return -1; } // Shutdown
get STATE_IDLE() { return 0; }
get STATE_REQ() { return 1; }
get STATE_RESP() { return 2; }
get STATE_REQ_P() { return 3; } // Request has multiple parts
get STATE_RESP_P() { return 4; } // Response has multiple parts
get STATE_AWAIT() { return 5; } // Awaiting the next part
get STATE_REQ_FAILED() { return 6; } // The Request failed
get STATE_RESET() { return 7; } // Reset to a known state
get_msg_len() { return this.msg_char_len; }
get_msg_buffer() { return this.msg_buf; }
get_comm_buffer() { return this.comm_buf; }
send_msg(msg) {
try {
// const state = Atomics.load(this.comm, this.STATE_IDX);
// if (state !== this.STATE_IDLE) console.debug(`MONO_WASM_ENCRYPT_DECRYPT: send_msg, waiting for idle now, ${state}`);
this.wait_for_state(pstate => pstate == this.STATE_IDLE, "waiting");
this.send_request(msg);
return this.read_response();
}
catch (err) {
this.reset(LibraryChannel._stringify_err(err));
throw err;
}
finally {
// const state = Atomics.load(this.comm, this.STATE_IDX);
// if (state !== this.STATE_IDLE) console.debug(`MONO_WASM_ENCRYPT_DECRYPT: state at end of send_msg: ${state}`);
}
}
shutdown() {
// console.debug("MONO_WASM_ENCRYPT_DECRYPT: Shutting down crypto");
const state = Atomics.load(this.comm, this.STATE_IDX);
if (state !== this.STATE_IDLE)
throw new Error(`OWNER: Invalid sync communication channel state: ${state}`);
// Notify webworker
Atomics.store(this.comm, this.MSG_SIZE_IDX, 0);
this._change_state_locked(this.STATE_SHUTDOWN);
Atomics.notify(this.comm, this.STATE_IDX);
}
// eslint-disable-next-line @typescript-eslint/no-unused-vars
reset(reason) {
// console.debug(`MONO_WASM_ENCRYPT_DECRYPT: reset: ${reason}`);
const state = Atomics.load(this.comm, this.STATE_IDX);
if (state === this.STATE_SHUTDOWN)
return;
if (state === this.STATE_RESET || state === this.STATE_IDLE) {
// console.debug(`MONO_WASM_ENCRYPT_DECRYPT: state is already RESET or idle: ${state}`);
return;
}
Atomics.store(this.comm, this.MSG_SIZE_IDX, 0);
this._change_state_locked(this.STATE_RESET);
Atomics.notify(this.comm, this.STATE_IDX);
}
send_request(msg) {
let state;
const msg_len = msg.length;
let msg_written = 0;
for (;;) {
this.acquire_lock();
try {
// Write the message and return how much was written.
const wrote = this.write_to_msg(msg, msg_written, msg_len);
msg_written += wrote;
// Indicate how much was written to the this.msg buffer.
Atomics.store(this.comm, this.MSG_SIZE_IDX, wrote);
// Indicate if this was the whole message or part of it.
state = msg_written === msg_len ? this.STATE_REQ : this.STATE_REQ_P;
// Notify webworker
this._change_state_locked(state);
}
finally {
this.release_lock();
}
Atomics.notify(this.comm, this.STATE_IDX);
// The send message is complete.
if (state === this.STATE_REQ)
break;
this.wait_for_state(state => state == this.STATE_AWAIT, "send_request");
}
}
write_to_msg(input, start, input_len) {
let mi = 0;
let ii = start;
while (mi < this.msg_char_len && ii < input_len) {
this.msg[mi] = input.charCodeAt(ii);
ii++; // Next character
mi++; // Next buffer index
}
return ii - start;
}
read_response() {
let response = "";
for (;;) {
const state = this.wait_for_state(state => state == this.STATE_RESP || state == this.STATE_RESP_P, "read_response");
this.acquire_lock();
try {
const size_to_read = Atomics.load(this.comm, this.MSG_SIZE_IDX);
// Append the latest part of the message.
response += this.read_from_msg(0, size_to_read);
// The response is complete.
if (state === this.STATE_RESP) {
Atomics.store(this.comm, this.MSG_SIZE_IDX, 0);
break;
}
// Reset the size and transition to await state.
Atomics.store(this.comm, this.MSG_SIZE_IDX, 0);
this._change_state_locked(this.STATE_AWAIT);
}
finally {
this.release_lock();
}
Atomics.notify(this.comm, this.STATE_IDX);
}
// Reset the communication channel's state and let the
// webworker know we are done.
this._change_state_locked(this.STATE_IDLE);
Atomics.notify(this.comm, this.STATE_IDX);
return response;
}
_change_state_locked(newState) {
Atomics.store(this.comm, this.STATE_IDX, newState);
}
wait_for_state(is_ready, msg) {
// Wait for webworker
// - Atomics.wait() is not permissible on the main thread.
for (;;) {
const lock_state = Atomics.load(this.comm, this.LOCK_IDX);
if (lock_state !== this.LOCK_UNLOCKED)
continue;
const state = Atomics.load(this.comm, this.STATE_IDX);
if (state == this.STATE_REQ_FAILED)
throw new OperationFailedError(`Worker failed during ${msg} with state=${state}`);
if (is_ready(state))
return state;
}
}
read_from_msg(begin, end) {
const slicedMessage = [];
this.msg.slice(begin, end).forEach((value, index) => slicedMessage[index] = value);
return String.fromCharCode.apply(null, slicedMessage);
}
acquire_lock() {
for (;;) {
const lock_state = Atomics.compareExchange(this.comm, this.LOCK_IDX, this.LOCK_UNLOCKED, this.LOCK_OWNED);
if (lock_state === this.LOCK_UNLOCKED) {
const state = Atomics.load(this.comm, this.STATE_IDX);
if (state === this.STATE_REQ_FAILED)
throw new OperationFailedError("Worker failed");
return;
}
}
}
release_lock() {
const result = Atomics.compareExchange(this.comm, this.LOCK_IDX, this.LOCK_OWNED, this.LOCK_UNLOCKED);
if (result !== this.LOCK_OWNED) {
throw new Error("CRYPTO: LibraryChannel tried to release a lock that wasn't acquired: " + result);
}
}
static _stringify_err(err) {
return (err instanceof Error && err.stack !== undefined) ? err.stack : err;
}
static create(msg_char_len) {
if (msg_char_len === undefined) {
msg_char_len = 1024; // Default size is arbitrary but is in 'char' units (i.e. UTF-16 code points).
}
return new LibraryChannel(msg_char_len);
}
}
// Licensed to the .NET Foundation under one or more agreements.
const MainThread = {
get pthread_id() {
return getBrowserThreadID();
},
isBrowserThread: true
};
let browser_thread_id_lazy;
function getBrowserThreadID() {
if (browser_thread_id_lazy === undefined) {
browser_thread_id_lazy = Module["_emscripten_main_browser_thread_id"]();
}
return browser_thread_id_lazy;
}
function isMonoThreadMessage(x) {
if (typeof (x) !== "object" || x === null) {
return false;
}
const xmsg = x;
return typeof (xmsg.type) === "string" && typeof (xmsg.cmd) === "string";
}
/// Messages sent using the worker object's postMessage() method ///
/// a symbol that we use as a key on messages on the global worker-to-main channel to identify our own messages
/// we can't use an actual JS Symbol because those don't transfer between workers.
const monoSymbol = "__mono_message_please_dont_collide__"; //Symbol("mono");
function makeChannelCreatedMonoMessage(thread_id, port) {
return {
[monoSymbol]: {
mono_cmd: "channel_created",
thread_id,
port
}
};
}
function isMonoWorkerMessage(message) {
return message !== undefined && typeof message === "object" && message !== null && monoSymbol in message;
}
function isMonoWorkerMessageChannelCreated(message) {
if (isMonoWorkerMessage(message)) {
const monoMessage = message[monoSymbol];
if (monoMessage.mono_cmd === "channel_created") {
return true;
}
}
return false;
}
// Licensed to the .NET Foundation under one or more agreements.
const threads = new Map();
class ThreadImpl {
constructor(pthread_ptr, worker, port) {
this.pthread_ptr = pthread_ptr;
this.worker = worker;
this.port = port;
}
postMessageToWorker(message) {
this.port.postMessage(message);
}
}
const thread_promises = new Map();
/// wait until the thread with the given id has set up a message port to the runtime
function waitForThread(pthread_ptr) {
if (threads.has(pthread_ptr)) {
return Promise.resolve(threads.get(pthread_ptr));
}
const promiseAndController = createPromiseController();
const arr = thread_promises.get(pthread_ptr);
if (arr === undefined) {
thread_promises.set(pthread_ptr, [promiseAndController.promise_control]);
}
else {
arr.push(promiseAndController.promise_control);
}
return promiseAndController.promise;
}
function resolvePromises(pthread_ptr, thread) {
const arr = thread_promises.get(pthread_ptr);
if (arr !== undefined) {
arr.forEach((controller) => controller.resolve(thread));
thread_promises.delete(pthread_ptr);
}
}
function addThread(pthread_ptr, worker, port) {
const thread = new ThreadImpl(pthread_ptr, worker, port);
threads.set(pthread_ptr, thread);
return thread;
}
function removeThread(pthread_ptr) {
threads.delete(pthread_ptr);
}
/// Given a thread id, return the thread object with the worker where the thread is running, and a message port.
function getThread(pthread_ptr) {
const thread = threads.get(pthread_ptr);
if (thread === undefined) {
return undefined;
}
// validate that the worker is still running pthread_ptr
const worker = thread.worker;
if (Internals.getThreadId(worker) !== pthread_ptr) {
removeThread(pthread_ptr);
thread.port.close();
return undefined;
}
return thread;
}
/// Returns all the threads we know about
const getThreadIds = () => threads.keys();
function monoDedicatedChannelMessageFromWorkerToMain(event, thread) {
// TODO: add callbacks that will be called from here
console.debug("MONO_WASM: got message from worker on the dedicated channel", event.data, thread);
}
// handler that runs in the main thread when a message is received from a pthread worker
function monoWorkerMessageHandler(worker, ev) {
/// N.B. important to ignore messages we don't recognize - Emscripten uses the message event to send internal messages
const data = ev.data;
if (isMonoWorkerMessageChannelCreated(data)) {
console.debug("MONO_WASM: received the channel created message", data, worker);
const port = data[monoSymbol].port;
const pthread_id = data[monoSymbol].thread_id;
const thread = addThread(pthread_id, worker, port);
port.addEventListener("message", (ev) => monoDedicatedChannelMessageFromWorkerToMain(ev, thread));
port.start();
resolvePromises(pthread_id, thread);
}
}
/// Called by Emscripten internals on the browser thread when a new pthread worker is created and added to the pthread worker pool.
/// At this point the worker doesn't have any pthread assigned to it, yet.
function afterLoadWasmModuleToWorker(worker) {
worker.addEventListener("message", (ev) => monoWorkerMessageHandler(worker, ev));
console.debug("MONO_WASM: afterLoadWasmModuleToWorker added message event handler", worker);
}
/// These utility functions dig into Emscripten internals
const Internals = {
getWorker: (pthread_ptr) => {
// see https://github.com/emscripten-core/emscripten/pull/16239
return Module.PThread.pthreads[pthread_ptr].worker;
},
getThreadId: (worker) => {
/// See library_pthread.js in Emscripten.
/// They hang a "pthread" object from the worker if the worker is running a thread, and remove it when the thread stops by doing `pthread_exit` or when it's joined using `pthread_join`.
const emscriptenThreadInfo = worker["pthread"];
if (emscriptenThreadInfo === undefined) {
return undefined;
}
return emscriptenThreadInfo.threadInfoStruct;
}
};
const dotnetPthreadCreated = "dotnet:pthread:created";
const dotnetPthreadAttached = "dotnet:pthread:attached";
let WorkerThreadEventClassConstructor;
const makeWorkerThreadEvent = !MonoWasmThreads
? (() => { throw new Error("threads support disabled"); })
: ((type, pthread_self) => {
if (!WorkerThreadEventClassConstructor)
WorkerThreadEventClassConstructor = class WorkerThreadEventImpl extends Event {
constructor(type, pthread_self) {
super(type);
this.pthread_self = pthread_self;
}
};
return new WorkerThreadEventClassConstructor(type, pthread_self);
});
// Licensed to the .NET Foundation under one or more agreements.
class WorkerSelf {
constructor(pthread_id, portToBrowser) {
this.pthread_id = pthread_id;
this.portToBrowser = portToBrowser;
this.isBrowserThread = false;
}
postMessageToBrowser(message, transfer) {
if (transfer) {
this.portToBrowser.postMessage(message, transfer);
}
else {
this.portToBrowser.postMessage(message);
}
}
addEventListenerFromBrowser(listener) {
this.portToBrowser.addEventListener("message", listener);
}
}
// we are lying that this is never null, but afterThreadInit should be the first time we get to run any code
// in the worker, so this becomes non-null very early.
let pthread_self = null;
/// This is the "public internal" API for runtime subsystems that wish to be notified about
/// pthreads that are running on the current worker.
/// Example:
/// currentWorkerThreadEvents.addEventListener(dotnetPthreadCreated, (ev: WorkerThreadEvent) => {
/// console.debug("MONO_WASM: thread created on worker with id", ev.pthread_ptr);
/// });
const currentWorkerThreadEvents = MonoWasmThreads ? new EventTarget() : null; // treeshake if threads are disabled
function monoDedicatedChannelMessageFromMainToWorker(event) {
console.debug("MONO_WASM: got message from main on the dedicated channel", event.data);
}
function setupChannelToMainThread(pthread_ptr) {
console.debug("MONO_WASM: creating a channel", pthread_ptr);
const channel = new MessageChannel();
const workerPort = channel.port1;
const mainPort = channel.port2;
workerPort.addEventListener("message", monoDedicatedChannelMessageFromMainToWorker);
workerPort.start();
pthread_self = new WorkerSelf(pthread_ptr, workerPort);
self.postMessage(makeChannelCreatedMonoMessage(pthread_ptr, mainPort), [mainPort]);
return pthread_self;
}
/// This is an implementation detail function.
/// Called in the worker thread from mono when a pthread becomes attached to the mono runtime.
function mono_wasm_pthread_on_pthread_attached(pthread_id) {
const self = pthread_self;
if (!(self !== null && self.pthread_id == pthread_id)) throw new Error("Assert failed: expected pthread_self to be set already when attaching"); // inlined mono_assert
console.debug("MONO_WASM: attaching pthread to runtime", pthread_id);
currentWorkerThreadEvents.dispatchEvent(makeWorkerThreadEvent(dotnetPthreadAttached, self));
}
/// This is an implementation detail function.
/// Called by emscripten when a pthread is setup to run on a worker. Can be called multiple times
/// for the same worker, since emscripten can reuse workers. This is an implementation detail, that shouldn't be used directly.
function afterThreadInitTLS() {
// don't do this callback for the main thread
if (ENVIRONMENT_IS_PTHREAD) {
const pthread_ptr = Module["_pthread_self"]();
if (!(!is_nullish(pthread_ptr))) throw new Error("Assert failed: pthread_self() returned null"); // inlined mono_assert
console.debug("MONO_WASM: after thread init, pthread ptr", pthread_ptr);
const self = setupChannelToMainThread(pthread_ptr);
currentWorkerThreadEvents.dispatchEvent(makeWorkerThreadEvent(dotnetPthreadCreated, self));
}
}
let node_fs = undefined;
let node_url = undefined;
function init_polyfills(replacements) {
const anyModule = Module;
// performance.now() is used by emscripten and doesn't work in JSC
if (typeof globalThis.performance === "undefined") {
globalThis.performance = dummyPerformance;
}
if (typeof globalThis.URL === "undefined") {
globalThis.URL = class URL {
constructor(url) {
this.url = url;
}
toString() {
return this.url;
}
};
}
// v8 shell doesn't have Event and EventTarget
if (MonoWasmThreads && typeof globalThis.Event === "undefined") {
globalThis.Event = class Event {
constructor(type) {
this.type = type;
}
};
}
if (MonoWasmThreads && typeof globalThis.EventTarget === "undefined") {
globalThis.EventTarget = class EventTarget {
constructor() {
this.subscribers = new Map();
}
addEventListener(type, listener, options) {
if (listener === undefined || listener == null)
return;
let oneShot = false;
if (options !== undefined) {
for (const [k, v] of Object.entries(options)) {
if (k === "once") {
oneShot = v ? true : false;
continue;
}
throw new Error(`FIXME: addEventListener polyfill doesn't implement option '${k}'`);
}
}
if (!this.subscribers.has(type)) {
this.subscribers.set(type, []);
}
const listeners = this.subscribers.get(type);
if (listeners === undefined) {
throw new Error("can't happen");
}
listeners.push({ listener, oneShot });
}
removeEventListener(type, listener, options) {
if (listener === undefined || listener == null)
return;
if (options !== undefined) {
throw new Error("FIXME: removeEventListener polyfill doesn't implement options");
}
if (!this.subscribers.has(type)) {
return;
}
const subscribers = this.subscribers.get(type);
if (subscribers === undefined)
return;
let index = -1;
const n = subscribers.length;
for (let i = 0; i < n; ++i) {
if (subscribers[i].listener === listener) {
index = i;
break;
}
}
if (index > -1) {
subscribers.splice(index, 1);
}
}
dispatchEvent(event) {
if (!this.subscribers.has(event.type)) {
return true;
}
let subscribers = this.subscribers.get(event.type);
if (subscribers === undefined) {
return true;
}
let needsCopy = false;
for (const sub of subscribers) {
if (sub.oneShot) {
needsCopy = true;
break;
}
}
if (needsCopy) {
subscribers = subscribers.slice(0);
}
for (const sub of subscribers) {
const listener = sub.listener;
if (sub.oneShot) {
this.removeEventListener(event.type, listener);
}
if (typeof listener === "function") {
listener.call(this, event);
}
else {
listener.handleEvent(event);
}
}
return true;
}
};
}
// require replacement
const imports = anyModule.imports = Module.imports || {};
const requireWrapper = (wrappedRequire) => (name) => {
const resolved = Module.imports[name];
if (resolved) {
return resolved;
}
return wrappedRequire(name);
};
if (imports.require) {
runtimeHelpers.requirePromise = replacements.requirePromise = Promise.resolve(requireWrapper(imports.require));
}
else if (replacements.require) {
runtimeHelpers.requirePromise = replacements.requirePromise = Promise.resolve(requireWrapper(replacements.require));
}
else if (replacements.requirePromise) {
runtimeHelpers.requirePromise = replacements.requirePromise.then(require => requireWrapper(require));
}
else {
runtimeHelpers.requirePromise = replacements.requirePromise = Promise.resolve(requireWrapper((name) => {
throw new Error(`Please provide Module.imports.${name} or Module.imports.require`);
}));
}
// script location
runtimeHelpers.scriptDirectory = replacements.scriptDirectory = detectScriptDirectory(replacements);
anyModule.mainScriptUrlOrBlob = replacements.scriptUrl; // this is needed by worker threads
if (Configuration === "Debug") {
console.debug(`MONO_WASM: starting script ${replacements.scriptUrl}`);
console.debug(`MONO_WASM: starting in ${runtimeHelpers.scriptDirectory}`);
}
if (anyModule.__locateFile === anyModule.locateFile) {
// above it's our early version from dotnet.es6.pre.js, we could replace it with better
anyModule.locateFile = runtimeHelpers.locateFile = (path) => {
if (isPathAbsolute(path))
return path;
return runtimeHelpers.scriptDirectory + path;
};
}
else {
// we use what was given to us
runtimeHelpers.locateFile = anyModule.locateFile;
}
// fetch poly
if (imports.fetch) {
replacements.fetch = runtimeHelpers.fetch_like = imports.fetch;
}
else {
replacements.fetch = runtimeHelpers.fetch_like = fetch_like;
}
// misc
replacements.noExitRuntime = ENVIRONMENT_IS_WEB;
// threads
if (MonoWasmThreads) {
if (replacements.pthreadReplacements) {
const originalLoadWasmModuleToWorker = replacements.pthreadReplacements.loadWasmModuleToWorker;
replacements.pthreadReplacements.loadWasmModuleToWorker = (worker, onFinishedLoading) => {
originalLoadWasmModuleToWorker(worker, onFinishedLoading);
afterLoadWasmModuleToWorker(worker);
};
const originalThreadInitTLS = replacements.pthreadReplacements.threadInitTLS;
replacements.pthreadReplacements.threadInitTLS = () => {
originalThreadInitTLS();
afterThreadInitTLS();
};
}
}
// memory
const originalUpdateGlobalBufferAndViews = replacements.updateGlobalBufferAndViews;
replacements.updateGlobalBufferAndViews = (buffer) => {
originalUpdateGlobalBufferAndViews(buffer);
afterUpdateGlobalBufferAndViews(buffer);
};
}
async function init_polyfills_async() {
if (ENVIRONMENT_IS_NODE && ENVIRONMENT_IS_ESM) {
// wait for locateFile setup on NodeJs
INTERNAL$1.require = await runtimeHelpers.requirePromise;
if (globalThis.performance === dummyPerformance) {
const { performance } = INTERNAL$1.require("perf_hooks");
globalThis.performance = performance;
}
}
}
const dummyPerformance = {
now: function () {
return Date.now();
}
};
async function fetch_like(url, init) {
try {
if (ENVIRONMENT_IS_NODE) {
if (!node_fs) {
const node_require = await runtimeHelpers.requirePromise;
node_url = node_require("url");
node_fs = node_require("fs");
}
if (url.startsWith("file://")) {
url = node_url.fileURLToPath(url);
}
const arrayBuffer = await node_fs.promises.readFile(url);
return {
ok: true,
url,
arrayBuffer: () => arrayBuffer,
json: () => JSON.parse(arrayBuffer)
};
}
else if (typeof (globalThis.fetch) === "function") {
return globalThis.fetch(url, init || { credentials: "same-origin" });
}
else if (typeof (read) === "function") {
// note that it can't open files with unicode names, like Stra<unicode char - Latin Small Letter Sharp S>e.xml
// https://bugs.chromium.org/p/v8/issues/detail?id=12541
const arrayBuffer = new Uint8Array(read(url, "binary"));
return {
ok: true,
url,
arrayBuffer: () => arrayBuffer,
json: () => JSON.parse(Module.UTF8ArrayToString(arrayBuffer, 0, arrayBuffer.length))
};
}
}
catch (e) {
return {
ok: false,
url,
arrayBuffer: () => { throw e; },
json: () => { throw e; }
};
}
throw new Error("No fetch implementation available");
}
function normalizeFileUrl(filename) {
// unix vs windows
// remove query string
return filename.replace(/\\/g, "/").replace(/[?#].*/, "");
}
function normalizeDirectoryUrl(dir) {
return dir.slice(0, dir.lastIndexOf("/")) + "/";
}
function detectScriptDirectory(replacements) {
if (ENVIRONMENT_IS_WORKER) {
// Check worker, not web, since window could be polyfilled
replacements.scriptUrl = self.location.href;
}
// when ENVIRONMENT_IS_ESM we have scriptUrl from import.meta.url from dotnet.es6.lib.js
if (!ENVIRONMENT_IS_ESM) {
if (ENVIRONMENT_IS_WEB) {
if ((typeof (globalThis.document) === "object") &&
(typeof (globalThis.document.createElement) === "function")) {
// blazor injects a module preload link element for dotnet.[version].[sha].js
const blazorDotNetJS = Array.from(document.head.getElementsByTagName("link")).filter(elt => elt.rel !== undefined && elt.rel == "modulepreload" && elt.href !== undefined && elt.href.indexOf("dotnet") != -1 && elt.href.indexOf(".js") != -1);
if (blazorDotNetJS.length == 1) {
replacements.scriptUrl = blazorDotNetJS[0].href;
}
else {
const temp = globalThis.document.createElement("a");
temp.href = "dotnet.js";
replacements.scriptUrl = temp.href;
}
}
}
if (ENVIRONMENT_IS_NODE) {
if (typeof __filename !== "undefined") {
// unix vs windows
replacements.scriptUrl = __filename;
}
}
}
if (!replacements.scriptUrl) {
// probably V8 shell in non ES6
replacements.scriptUrl = "./dotnet.js";
}
replacements.scriptUrl = normalizeFileUrl(replacements.scriptUrl);
return normalizeDirectoryUrl(replacements.scriptUrl);
}
const protocolRx = /^[a-zA-Z][a-zA-Z\d+\-.]*?:\/\//;
const windowsAbsoluteRx = /[a-zA-Z]:[\\/]/;
function isPathAbsolute(path) {
if (ENVIRONMENT_IS_NODE || ENVIRONMENT_IS_SHELL) {
// unix /x.json
// windows \x.json
// windows C:\x.json
// windows C:/x.json
return path.startsWith("/") || path.startsWith("\\") || path.indexOf("///") !== -1 || windowsAbsoluteRx.test(path);
}
// anything with protocol is always absolute
// windows file:///C:/x.json
// windows http://C:/x.json
return protocolRx.test(path);
}
// Licensed to the .NET Foundation under one or more agreements.
function isDiagnosticMessage(x) {
return isMonoThreadMessage(x) && x.type === "diagnostic_server";
}
function makeDiagnosticServerControlCommand(cmd) {
return {
type: "diagnostic_server",
cmd: cmd,
};
}
// Licensed to the .NET Foundation under one or more agreements.
class ServerControllerImpl {
constructor(server) {
this.server = server;
server.port.addEventListener("message", this.onServerReply.bind(this));
}
start() {
console.debug("MONO_WASM: signaling the diagnostic server to start");
this.server.postMessageToWorker(makeDiagnosticServerControlCommand("start"));
}
stop() {
console.debug("MONO_WASM: signaling the diagnostic server to stop");
this.server.postMessageToWorker(makeDiagnosticServerControlCommand("stop"));
}
postServerAttachToRuntime() {
console.debug("MONO_WASM: signal the diagnostic server to attach to the runtime");
this.server.postMessageToWorker(makeDiagnosticServerControlCommand("attach_to_runtime"));
}
onServerReply(event) {
const d = event.data;
if (isDiagnosticMessage(d)) {
switch (d.cmd) {
default:
console.warn("MONO_WASM: Unknown control reply command: ", d);
break;
}
}
}
}
let serverController = null;
function getController() {
if (serverController)
return serverController;
throw new Error("unexpected no server controller");
}
async function startDiagnosticServer(websocket_url) {
const sizeOfPthreadT = 4;
console.info(`MONO_WASM: starting the diagnostic server url: ${websocket_url}`);
const result = withStackAlloc(sizeOfPthreadT, (pthreadIdPtr) => {
if (!wrapped_c_functions.mono_wasm_diagnostic_server_create_thread(websocket_url, pthreadIdPtr))
return undefined;
const pthreadId = getI32(pthreadIdPtr);
return pthreadId;
});
if (result === undefined) {
console.warn("MONO_WASM: diagnostic server failed to start");
return null;
}
// have to wait until the message port is created
const thread = await waitForThread(result);
if (thread === undefined) {
throw new Error("unexpected diagnostic server thread not found");
}
const serverControllerImpl = new ServerControllerImpl(thread);
serverController = serverControllerImpl;
serverControllerImpl.start();
return serverControllerImpl;
}
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
const eventLevel = {
LogAlways: 0,
Critical: 1,
Error: 2,
Warning: 3,
Informational: 4,
Verbose: 5,
};
const runtimeProviderName = "Microsoft-Windows-DotNETRuntime";
const runtimePrivateProviderName = "Microsoft-Windows-DotNETRuntimePrivate";
const sampleProfilerProviderName = "Microsoft-DotNETCore-SampleProfiler";
const runtimeProviderDefault = {
name: runtimeProviderName,
keyword_mask: "4c14fccbd",
level: eventLevel.Verbose,
};
const runtimePrivateProviderDefault = {
name: runtimePrivateProviderName,
keyword_mask: "4002000b",
level: eventLevel.Verbose,
};
const sampleProfilerProviderDefault = {
name: sampleProfilerProviderName,
keyword_mask: "0",
level: eventLevel.Verbose,
};
/// A helper class to create EventPipeSessionOptions
class SessionOptionsBuilder {
/// Create an empty builder. Prefer to use SessionOptionsBuilder.Empty
constructor() {
this._providers = [];
}
/// Gets a builder with no providers.
static get Empty() { return new SessionOptionsBuilder(); }
/// Gets a builder with default providers and rundown events enabled.
/// See https://docs.microsoft.com/en-us/dotnet/core/diagnostics/eventpipe#trace-using-environment-variables
static get DefaultProviders() {
return this.Empty.addRuntimeProvider().addRuntimePrivateProvider().addSampleProfilerProvider();
}
/// Change whether to collect rundown events.
/// Certain providers may need rundown events to be collected in order to provide useful diagnostic information.
setRundownEnabled(enabled) {
this._rundown = enabled;
return this;
}
/// Add a provider configuration to the builder.
addProvider(provider) {
this._providers.push(provider);
return this;
}
/// Add the Microsoft-Windows-DotNETRuntime provider. Use override options to change the event level or keyword mask.
/// The default is { keyword_mask: "4c14fccbd", level: eventLevel.Verbose }
addRuntimeProvider(overrideOptions) {
const options = { ...runtimeProviderDefault, ...overrideOptions };
this._providers.push(options);
return this;
}
/// Add the Microsoft-Windows-DotNETRuntimePrivate provider. Use override options to change the event level or keyword mask.
/// The default is { keyword_mask: "4002000b", level: eventLevel.Verbose}
addRuntimePrivateProvider(overrideOptions) {
const options = { ...runtimePrivateProviderDefault, ...overrideOptions };
this._providers.push(options);
return this;
}
/// Add the Microsoft-DotNETCore-SampleProfiler. Use override options to change the event level or keyword mask.
// The default is { keyword_mask: 0, level: eventLevel.Verbose }
addSampleProfilerProvider(overrideOptions) {
const options = { ...sampleProfilerProviderDefault, ...overrideOptions };
this._providers.push(options);
return this;
}
/// Create an EventPipeSessionOptions from the builder.
build() {
const providers = this._providers.map(p => {
var _a, _b, _c;
const name = p.name;
const keyword_mask = "" + ((_a = p === null || p === void 0 ? void 0 : p.keyword_mask) !== null && _a !== void 0 ? _a : "");
const level = (_b = p === null || p === void 0 ? void 0 : p.level) !== null && _b !== void 0 ? _b : eventLevel.Verbose;
const args = (_c = p === null || p === void 0 ? void 0 : p.args) !== null && _c !== void 0 ? _c : "";
const maybeArgs = args != "" ? `:${args}` : "";
return `${name}:${keyword_mask}:${level}${maybeArgs}`;
});
return {
collectRundownEvents: this._rundown,
providers: providers.join(",")
};
}
}
// Licensed to the .NET Foundation under one or more agreements.
const sizeOfInt32 = 4;
function createSessionWithPtrCB(sessionIdOutPtr, options, sessionType) {
setI32(sessionIdOutPtr, 0);
let tracePath;
let ipcStreamAddr;
if (sessionType.type === "file") {
tracePath = sessionType.filePath;
ipcStreamAddr = 0;
}
else {
tracePath = null;
ipcStreamAddr = sessionType.stream;
}
if (!wrapped_c_functions.mono_wasm_event_pipe_enable(tracePath, ipcStreamAddr, options.bufferSizeInMB, options.providers, options.rundownRequested, sessionIdOutPtr)) {
return false;
}
else {
return getU32(sessionIdOutPtr);
}
}
function createEventPipeStreamingSession(ipcStreamAddr, options) {
return withStackAlloc(sizeOfInt32, createSessionWithPtrCB, options, { type: "stream", stream: ipcStreamAddr });
}
function createEventPipeFileSession(tracePath, options) {
return withStackAlloc(sizeOfInt32, createSessionWithPtrCB, options, { type: "file", filePath: tracePath });
}
// internal session state of the JS instance
var State;
(function (State) {
State[State["Initialized"] = 0] = "Initialized";
State[State["Started"] = 1] = "Started";
State[State["Done"] = 2] = "Done";
})(State || (State = {}));
/// An EventPipe session that saves the event data to a file in the VFS.
class EventPipeFileSession {
constructor(sessionID, tracePath) {
this.start = () => {
if (this._state !== State.Initialized) {
throw new Error(`MONO_WASM: EventPipe session ${this.sessionID} already started`);
}
this._state = State.Started;
start_streaming(this._sessionID);
console.debug(`MONO_WASM: EventPipe session ${this.sessionID} started`);
};
this.stop = () => {
if (this._state !== State.Started) {
throw new Error(`cannot stop an EventPipe session in state ${this._state}, not 'Started'`);
}
this._state = State.Done;
stop_streaming(this._sessionID);
console.debug(`MONO_WASM: EventPipe session ${this.sessionID} stopped`);
};
this.getTraceBlob = () => {
if (this._state !== State.Done) {
throw new Error(`session is in state ${this._state}, not 'Done'`);
}
const data = Module.FS_readFile(this._tracePath, { encoding: "binary" });
return new Blob([data], { type: "application/octet-stream" });
};
this._state = State.Initialized;
this._sessionID = sessionID;
this._tracePath = tracePath;
console.debug(`MONO_WASM: EventPipe session ${this.sessionID} created`);
}
get sessionID() { return BigInt(this._sessionID); }
}
function start_streaming(sessionID) {
wrapped_c_functions.mono_wasm_event_pipe_session_start_streaming(sessionID);
}
function stop_streaming(sessionID) {
wrapped_c_functions.mono_wasm_event_pipe_session_disable(sessionID);
}
// a conter for the number of sessions created
let totalSessions = 0;
function makeEventPipeSession(options) {
var _a, _b;
const defaultRundownRequested = true;
const defaultProviders = ""; // empty string means use the default providers
const defaultBufferSizeInMB = 1;
const rundown = (_a = options === null || options === void 0 ? void 0 : options.collectRundownEvents) !== null && _a !== void 0 ? _a : defaultRundownRequested;
const providers = (_b = options === null || options === void 0 ? void 0 : options.providers) !== null && _b !== void 0 ? _b : defaultProviders;
// The session trace is saved to a file in the VFS. The file name doesn't matter,
// but we'd like it to be distinct from other traces.
const tracePath = `/trace-${totalSessions++}.nettrace`;
const sessionOptions = {
rundownRequested: rundown,
providers: providers,
bufferSizeInMB: defaultBufferSizeInMB,
};
const success = createEventPipeFileSession(tracePath, sessionOptions);
if (success === false)
return null;
const sessionID = success;
return new EventPipeFileSession(sessionID, tracePath);
}
// Licensed to the .NET Foundation under one or more agreements.
let startup_session_configs = [];
let startup_sessions = null;
// called from C on the main thread
function mono_wasm_event_pipe_early_startup_callback() {
if (MonoWasmThreads) {
if (startup_session_configs === null || startup_session_configs.length == 0) {
return;
}
console.debug("MONO_WASM: diagnostics: setting startup sessions based on startup session configs", startup_session_configs);
startup_sessions = startup_session_configs.map(config => createAndStartEventPipeSession(config));
startup_session_configs = [];
}
}
function createAndStartEventPipeSession(options) {
const session = makeEventPipeSession(options);
if (session === null) {
return null;
}
session.start();
return session;
}
function getDiagnostics() {
if (MonoWasmThreads) {
return {
/// An enumeration of the level (higher value means more detail):
/// LogAlways: 0,
/// Critical: 1,
/// Error: 2,
/// Warning: 3,
/// Informational: 4,
/// Verbose: 5,
EventLevel: eventLevel,
/// A builder for creating an EventPipeSessionOptions instance.
SessionOptionsBuilder: SessionOptionsBuilder,
/// Creates a new EventPipe session that will collect trace events from the runtime and managed libraries.
/// Use the options to control the kinds of events to be collected.
/// Multiple sessions may be created and started at the same time.
createEventPipeSession: makeEventPipeSession,
getStartupSessions() {
return Array.from(startup_sessions || []);
},
};
}
else {
return undefined;
}
}
/// APIs for working with .NET diagnostics from JavaScript.
const diagnostics = getDiagnostics();
// Initialization flow
/// * The runtime calls configure_diagnostics with options from MonoConfig
/// * We start the diagnostic server which connects to the host and waits for some configurations (an IPC CollectTracing command)
/// * The host sends us the configurations and we push them onto the startup_session_configs array and let the startup resume
/// * The runtime calls mono_wasm_initA_diagnostics with any options from MonoConfig
/// * The runtime C layer calls mono_wasm_event_pipe_early_startup_callback during startup once native EventPipe code is initialized
/// * We start all the sessiosn in startup_session_configs and allow them to start streaming
/// * The IPC sessions first send an IPC message with the session ID and then they start streaming
//// * If the diagnostic server gets more commands it will send us a message through the serverController and we will start additional sessions
let suspendOnStartup = false;
let diagnosticsServerEnabled = false;
async function mono_wasm_init_diagnostics(options) {
var _a;
if (!MonoWasmThreads) {
console.warn("MONO_WASM: ignoring diagnostics options because this runtime does not support diagnostics", options);
return;
}
else {
if (!is_nullish(options.server)) {
if (options.server.connect_url === undefined || typeof (options.server.connect_url) !== "string") {
throw new Error("server.connect_url must be a string");
}
const url = options.server.connect_url;
const suspend = boolsyOption(options.server.suspend);
const controller = await startDiagnosticServer(url);
if (controller) {
diagnosticsServerEnabled = true;
if (suspend) {
suspendOnStartup = true;
}
}
}
const sessions = (_a = options === null || options === void 0 ? void 0 : options.sessions) !== null && _a !== void 0 ? _a : [];
startup_session_configs.push(...sessions);
}
}
function boolsyOption(x) {
if (x === true || x === false)
return x;
if (typeof x === "string") {
if (x === "true")
return true;
if (x === "false")
return false;
}
throw new Error(`invalid option: "${x}", should be true, false, or "true" or "false"`);
}
function mono_wasm_diagnostic_server_on_runtime_server_init(out_options) {
if (diagnosticsServerEnabled) {
/* called on the main thread when the runtime is sufficiently initialized */
const controller = getController();
controller.postServerAttachToRuntime();
// FIXME: is this really the best place to do this?
setI32(out_options, suspendOnStartup ? 1 : 0);
}
}
// Licensed to the .NET Foundation under one or more agreements.
let all_assets_loaded_in_memory = null;
const loaded_files = [];
const loaded_assets = Object.create(null);
let instantiated_assets_count = 0;
let downloded_assets_count = 0;
const max_parallel_downloads = 100;
// in order to prevent net::ERR_INSUFFICIENT_RESOURCES if we start downloading too many files at same time
let parallel_count = 0;
let throttling_promise = undefined;
let throttling_promise_resolve = undefined;
let config = undefined;
const afterInstantiateWasm = createPromiseController();
const beforePreInit = createPromiseController();
const afterPreInit = createPromiseController();
const afterPreRun = createPromiseController();
const beforeOnRuntimeInitialized = createPromiseController();
const afterOnRuntimeInitialized = createPromiseController();
const afterPostRun = createPromiseController();
// we are making emscripten startup async friendly
// emscripten is executing the events without awaiting it and so we need to block progress via PromiseControllers above
function configure_emscripten_startup(module, exportedAPI) {
// these all could be overridden on DotnetModuleConfig, we are chaing them to async below, as opposed to emscripten
// when user set configSrc or config, we are running our default startup sequence.
const userInstantiateWasm = module.instantiateWasm;
const userPreInit = !module.preInit ? [] : typeof module.preInit === "function" ? [module.preInit] : module.preInit;
const userPreRun = !module.preRun ? [] : typeof module.preRun === "function" ? [module.preRun] : module.preRun;
const userpostRun = !module.postRun ? [] : typeof module.postRun === "function" ? [module.postRun] : module.postRun;
// eslint-disable-next-line @typescript-eslint/no-empty-function
const userOnRuntimeInitialized = module.onRuntimeInitialized ? module.onRuntimeInitialized : () => { };
const isCustomStartup = !module.configSrc && !module.config; // like blazor
// execution order == [0] ==
// - default or user Module.instantiateWasm (will start downloading dotnet.wasm)
module.instantiateWasm = (imports, callback) => instantiateWasm(imports, callback, userInstantiateWasm);
// execution order == [1] ==
module.preInit = [() => preInit(isCustomStartup, userPreInit)];
// execution order == [2] ==
module.preRun = [() => preRunAsync(userPreRun)];
// execution order == [4] ==
module.onRuntimeInitialized = () => onRuntimeInitializedAsync(isCustomStartup, userOnRuntimeInitialized);
// execution order == [5] ==
module.postRun = [() => postRunAsync(userpostRun)];
// execution order == [6] ==
module.ready = module.ready.then(async () => {
// wait for previous stage
await afterPostRun.promise;
// - here we resolve the promise returned by createDotnetRuntime export
return exportedAPI;
// - any code after createDotnetRuntime is executed now
});
// execution order == [*] ==
if (!module.onAbort) {
module.onAbort = () => mono_on_abort;
}
}
let wasm_module_imports = null;
let wasm_success_callback = null;
function instantiateWasm(imports, successCallback, userInstantiateWasm) {
// this is called so early that even Module exports like addRunDependency don't exist yet
if (!Module.configSrc && !Module.config && !userInstantiateWasm) {
Module.print("MONO_WASM: configSrc nor config was specified");
}
if (Module.config) {
config = runtimeHelpers.config = Module.config;
}
else {
config = runtimeHelpers.config = Module.config = {};
}
runtimeHelpers.diagnostic_tracing = !!config.diagnostic_tracing;
runtimeHelpers.enable_debugging = config.enable_debugging ? config.enable_debugging : 0;
if (!config.assets) {
config.assets = [];
}
if (userInstantiateWasm) {
const exports = userInstantiateWasm(imports, (instance, module) => {
afterInstantiateWasm.promise_control.resolve(null);
successCallback(instance, module);
});
return exports;
}
wasm_module_imports = imports;
wasm_success_callback = successCallback;
_instantiate_wasm_module();
return []; // No exports
}
function preInit(isCustomStartup, userPreInit) {
Module.addRunDependency("mono_pre_init");
try {
mono_wasm_pre_init_essential();
if (runtimeHelpers.diagnostic_tracing)
console.debug("MONO_WASM: preInit");
beforePreInit.promise_control.resolve(null);
// all user Module.preInit callbacks
userPreInit.forEach(fn => fn());
}
catch (err) {
_print_error("MONO_WASM: user preInint() failed", err);
abort_startup(err, true);
throw err;
}
// this will start immediately but return on first await.
// It will block our `preRun` by afterPreInit promise
// It will block emscripten `userOnRuntimeInitialized` by pending addRunDependency("mono_pre_init")
(async () => {
try {
await mono_wasm_pre_init_essential_async();
if (!isCustomStartup) {
// - download Module.config from configSrc
// - start download assets like DLLs
await mono_wasm_pre_init_full();
}
}
catch (err) {
abort_startup(err, true);
throw err;
}
// signal next stage
afterPreInit.promise_control.resolve(null);
Module.removeRunDependency("mono_pre_init");
})();
}
async function preRunAsync(userPreRun) {
Module.addRunDependency("mono_pre_run_async");
// wait for previous stages
await afterInstantiateWasm.promise;
await afterPreInit.promise;
if (runtimeHelpers.diagnostic_tracing)
console.debug("MONO_WASM: preRunAsync");
try {
// all user Module.preRun callbacks
userPreRun.map(fn => fn());
}
catch (err) {
_print_error("MONO_WASM: user callback preRun() failed", err);
abort_startup(err, true);
throw err;
}
// signal next stage
afterPreRun.promise_control.resolve(null);
Module.removeRunDependency("mono_pre_run_async");
}
async function onRuntimeInitializedAsync(isCustomStartup, userOnRuntimeInitialized) {
// wait for previous stage
await afterPreRun.promise;
if (runtimeHelpers.diagnostic_tracing)
console.debug("MONO_WASM: onRuntimeInitialized");
// signal this stage, this will allow pending assets to allocate memory
beforeOnRuntimeInitialized.promise_control.resolve(null);
try {
if (!isCustomStartup) {
// wait for all assets in memory
await all_assets_loaded_in_memory;
const expected_asset_count = config.assets ? config.assets.length : 0;
if (!(downloded_assets_count == expected_asset_count)) throw new Error("Assert failed: Expected assets to be downloaded"); // inlined mono_assert
if (!(instantiated_assets_count == expected_asset_count)) throw new Error("Assert failed: Expected assets to be in memory"); // inlined mono_assert
if (runtimeHelpers.diagnostic_tracing)
console.debug("MONO_WASM: all assets are loaded in wasm memory");
// load runtime
await mono_wasm_before_user_runtime_initialized();
}
// call user code
try {
userOnRuntimeInitialized();
}
catch (err) {
_print_error("MONO_WASM: user callback onRuntimeInitialized() failed", err);
throw err;
}
// finish
await mono_wasm_after_user_runtime_initialized();
}
catch (err) {
_print_error("MONO_WASM: onRuntimeInitializedAsync() failed", err);
abort_startup(err, true);
throw err;
}
// signal next stage
afterOnRuntimeInitialized.promise_control.resolve(null);
}
async function postRunAsync(userpostRun) {
// wait for previous stage
await afterOnRuntimeInitialized.promise;
if (runtimeHelpers.diagnostic_tracing)
console.debug("MONO_WASM: postRunAsync");
try {
// all user Module.postRun callbacks
userpostRun.map(fn => fn());
}
catch (err) {
_print_error("MONO_WASM: user callback posRun() failed", err);
abort_startup(err, true);
throw err;
}
// signal next stage
afterPostRun.promise_control.resolve(null);
}
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
function abort_startup(reason, should_exit) {
if (runtimeHelpers.diagnostic_tracing)
console.trace("MONO_WASM: abort_startup");
afterInstantiateWasm.promise_control.reject(reason);
beforePreInit.promise_control.reject(reason);
afterPreInit.promise_control.reject(reason);
afterPreRun.promise_control.reject(reason);
beforeOnRuntimeInitialized.promise_control.reject(reason);
afterOnRuntimeInitialized.promise_control.reject(reason);
afterPostRun.promise_control.reject(reason);
if (should_exit) {
set_exit_code(1, reason);
}
}
// runs in both blazor and non-blazor
function mono_wasm_pre_init_essential() {
Module.addRunDependency("mono_wasm_pre_init_essential");
if (runtimeHelpers.diagnostic_tracing)
console.debug("MONO_WASM: mono_wasm_pre_init_essential");
// init_polyfills() is already called from export.ts
init_crypto();
Module.removeRunDependency("mono_wasm_pre_init_essential");
}
// runs in both blazor and non-blazor
async function mono_wasm_pre_init_essential_async() {
if (runtimeHelpers.diagnostic_tracing)
console.debug("MONO_WASM: mono_wasm_pre_init_essential_async");
Module.addRunDependency("mono_wasm_pre_init_essential_async");
await init_polyfills_async();
if (MonoWasmThreads && ENVIRONMENT_IS_PTHREAD) {
await mono_wasm_pthread_worker_init();
}
Module.removeRunDependency("mono_wasm_pre_init_essential_async");
}
// runs just in non-blazor
async function mono_wasm_pre_init_full() {
if (runtimeHelpers.diagnostic_tracing)
console.debug("MONO_WASM: mono_wasm_pre_init_full");
Module.addRunDependency("mono_wasm_pre_init_full");
if (Module.configSrc) {
await mono_wasm_load_config(Module.configSrc);
}
await mono_download_assets();
Module.removeRunDependency("mono_wasm_pre_init_full");
}
// runs just in non-blazor
async function mono_wasm_before_user_runtime_initialized() {
if (runtimeHelpers.diagnostic_tracing)
console.debug("MONO_WASM: mono_wasm_before_user_runtime_initialized");
if (!Module.config || Module.config.isError) {
return;
}
try {
loaded_files.forEach(value => MONO$1.loaded_files.push(value.url));
if (!loaded_files || loaded_files.length == 0) {
Module.print("MONO_WASM: no files were loaded into runtime");
}
await _apply_configuration_from_args();
mono_wasm_globalization_init();
if (!runtimeHelpers.mono_wasm_load_runtime_done)
mono_wasm_load_runtime("unused", config.debug_level || 0);
if (!runtimeHelpers.mono_wasm_runtime_is_ready)
mono_wasm_runtime_ready();
setTimeout(() => {
// when there are free CPU cycles
string_decoder.init_fields();
});
}
catch (err) {
_print_error("MONO_WASM: Error in mono_wasm_before_user_runtime_initialized", err);
throw err;
}
}
// runs in both blazor and non-blazor
async function mono_wasm_after_user_runtime_initialized() {
if (runtimeHelpers.diagnostic_tracing)
console.debug("MONO_WASM: mono_wasm_after_user_runtime_initialized");
try {
if (!Module.disableDotnet6Compatibility && Module.exports) {
// Export emscripten defined in module through EXPORTED_RUNTIME_METHODS
// Useful to export IDBFS or other similar types generally exposed as
// global types when emscripten is not modularized.
const globalThisAny = globalThis;
for (let i = 0; i < Module.exports.length; ++i) {
const exportName = Module.exports[i];
const exportValue = Module[exportName];
if (exportValue != undefined) {
globalThisAny[exportName] = exportValue;
}
else {
console.warn(`MONO_WASM: The exported symbol ${exportName} could not be found in the emscripten module`);
}
}
}
if (runtimeHelpers.diagnostic_tracing)
console.debug("MONO_WASM: Initializing mono runtime");
if (Module.onDotnetReady) {
try {
await Module.onDotnetReady();
}
catch (err) {
_print_error("MONO_WASM: onDotnetReady () failed", err);
throw err;
}
}
}
catch (err) {
_print_error("MONO_WASM: Error in mono_wasm_after_user_runtime_initialized", err);
throw err;
}
}
function _print_error(message, err) {
Module.printErr(`${message}: ${JSON.stringify(err)}`);
if (err.stack) {
Module.printErr("MONO_WASM: Stacktrace: \n");
Module.printErr(err.stack);
}
}
// Set environment variable NAME to VALUE
// Should be called before mono_load_runtime_and_bcl () in most cases
function mono_wasm_setenv(name, value) {
wrapped_c_functions.mono_wasm_setenv(name, value);
}
function mono_wasm_set_runtime_options(options) {
if (!Array.isArray(options))
throw new Error("Expected runtime_options to be an array of strings");
const argv = Module._malloc(options.length * 4);
let aindex = 0;
for (let i = 0; i < options.length; ++i) {
const option = options[i];
if (typeof (option) !== "string")
throw new Error("Expected runtime_options to be an array of strings");
Module.setValue(argv + (aindex * 4), wrapped_c_functions.mono_wasm_strdup(option), "i32");
aindex += 1;
}
wrapped_c_functions.mono_wasm_parse_runtime_options(options.length, argv);
}
async function _instantiate_wasm_module() {
// this is called so early that even Module exports like addRunDependency don't exist yet
try {
if (!config.assets && Module.configSrc) {
// when we are starting with mono-config,json, it could have dotnet.wasm location in it, we have to wait for it
await mono_wasm_load_config(Module.configSrc);
}
if (runtimeHelpers.diagnostic_tracing)
console.debug("MONO_WASM: instantiateWasm");
let assetToLoad = {
name: "dotnet.wasm",
behavior: "dotnetwasm"
};
const assetfromConfig = config.assets.find(a => a.behavior === "dotnetwasm");
if (assetfromConfig) {
assetToLoad = assetfromConfig;
}
else {
config.assets.push(assetToLoad);
}
const pendingAsset = await start_asset_download(assetToLoad);
await beforePreInit.promise;
Module.addRunDependency("_instantiate_wasm_module");
if (!(pendingAsset && pendingAsset.pending)) throw new Error(`Assert failed: Can't load ${assetToLoad.name}`); // inlined mono_assert
const response = await pendingAsset.pending.response;
const contentType = response.headers ? response.headers.get("Content-Type") : undefined;
let compiledInstance;
let compiledModule;
if (typeof WebAssembly.instantiateStreaming === "function" && contentType === "application/wasm") {
if (runtimeHelpers.diagnostic_tracing)
console.debug("MONO_WASM: mono_wasm_after_user_runtime_initialized streaming");
const streamingResult = await WebAssembly.instantiateStreaming(response, wasm_module_imports);
compiledInstance = streamingResult.instance;
compiledModule = streamingResult.module;
}
else {
const arrayBuffer = await response.arrayBuffer();
if (runtimeHelpers.diagnostic_tracing)
console.debug("MONO_WASM: mono_wasm_after_user_runtime_initialized streaming");
const arrayBufferResult = await WebAssembly.instantiate(arrayBuffer, wasm_module_imports);
compiledInstance = arrayBufferResult.instance;
compiledModule = arrayBufferResult.module;
}
++instantiated_assets_count;
wasm_success_callback(compiledInstance, compiledModule);
if (runtimeHelpers.diagnostic_tracing)
console.debug("MONO_WASM: instantiateWasm done");
afterInstantiateWasm.promise_control.resolve(null);
wasm_success_callback = null;
wasm_module_imports = null;
}
catch (err) {
_print_error("MONO_WASM: _instantiate_wasm_module() failed", err);
abort_startup(err, true);
throw err;
}
Module.removeRunDependency("_instantiate_wasm_module");
}
// this need to be run only after onRuntimeInitialized event, when the memory is ready
function _instantiate_asset(asset, url, bytes) {
if (runtimeHelpers.diagnostic_tracing)
console.debug(`MONO_WASM: Loaded:${asset.name} as ${asset.behavior} size ${bytes.length} from ${url}`);
const virtualName = typeof (asset.virtual_path) === "string"
? asset.virtual_path
: asset.name;
let offset = null;
switch (asset.behavior) {
case "resource":
case "assembly":
case "pdb":
loaded_files.push({ url: url, file: virtualName });
// falls through
case "heap":
case "icu":
offset = mono_wasm_load_bytes_into_heap(bytes);
loaded_assets[virtualName] = [offset, bytes.length];
break;
case "vfs": {
// FIXME
const lastSlash = virtualName.lastIndexOf("/");
let parentDirectory = (lastSlash > 0)
? virtualName.substr(0, lastSlash)
: null;
let fileName = (lastSlash > 0)
? virtualName.substr(lastSlash + 1)
: virtualName;
if (fileName.startsWith("/"))
fileName = fileName.substr(1);
if (parentDirectory) {
if (runtimeHelpers.diagnostic_tracing)
console.debug(`MONO_WASM: Creating directory '${parentDirectory}'`);
Module.FS_createPath("/", parentDirectory, true, true // fixme: should canWrite be false?
);
}
else {
parentDirectory = "/";
}
if (runtimeHelpers.diagnostic_tracing)
console.debug(`MONO_WASM: Creating file '${fileName}' in directory '${parentDirectory}'`);
if (!mono_wasm_load_data_archive(bytes, parentDirectory)) {
Module.FS_createDataFile(parentDirectory, fileName, bytes, true /* canRead */, true /* canWrite */, true /* canOwn */);
}
break;
}
default:
throw new Error(`Unrecognized asset behavior:${asset.behavior}, for asset ${asset.name}`);
}
if (asset.behavior === "assembly") {
const hasPpdb = wrapped_c_functions.mono_wasm_add_assembly(virtualName, offset, bytes.length);
if (!hasPpdb) {
const index = loaded_files.findIndex(element => element.file == virtualName);
loaded_files.splice(index, 1);
}
}
else if (asset.behavior === "icu") {
if (!mono_wasm_load_icu_data(offset))
Module.printErr(`MONO_WASM: Error loading ICU asset ${asset.name}`);
}
else if (asset.behavior === "resource") {
wrapped_c_functions.mono_wasm_add_satellite_assembly(virtualName, asset.culture, offset, bytes.length);
}
++instantiated_assets_count;
}
// runs just in non-blazor
async function _apply_configuration_from_args() {
try {
const tz = Intl.DateTimeFormat().resolvedOptions().timeZone;
mono_wasm_setenv("TZ", tz || "UTC");
}
catch (_a) {
mono_wasm_setenv("TZ", "UTC");
}
for (const k in config.environment_variables) {
const v = config.environment_variables[k];
if (typeof (v) === "string")
mono_wasm_setenv(k, v);
else
throw new Error(`Expected environment variable '${k}' to be a string but it was ${typeof v}: '${v}'`);
}
if (config.runtime_options)
mono_wasm_set_runtime_options(config.runtime_options);
if (config.aot_profiler_options)
mono_wasm_init_aot_profiler(config.aot_profiler_options);
if (config.coverage_profiler_options)
mono_wasm_init_coverage_profiler(config.coverage_profiler_options);
if (config.diagnostic_options) {
await mono_wasm_init_diagnostics(config.diagnostic_options);
}
}
function mono_wasm_load_runtime(unused, debug_level) {
if (runtimeHelpers.diagnostic_tracing)
console.debug("MONO_WASM: mono_wasm_load_runtime");
if (runtimeHelpers.mono_wasm_load_runtime_done) {
return;
}
runtimeHelpers.mono_wasm_load_runtime_done = true;
try {
if (debug_level == undefined) {
debug_level = 0;
if (config && config.debug_level) {
debug_level = 0 + debug_level;
}
}
wrapped_c_functions.mono_wasm_load_runtime(unused || "unused", debug_level);
runtimeHelpers.wait_for_debugger = config.wait_for_debugger;
if (!runtimeHelpers.mono_wasm_bindings_is_ready)
bindings_init();
}
catch (err) {
_print_error("MONO_WASM: mono_wasm_load_runtime () failed", err);
abort_startup(err, false);
if (ENVIRONMENT_IS_SHELL || ENVIRONMENT_IS_NODE) {
const wasm_exit = wrapped_c_functions.mono_wasm_exit;
wasm_exit(1);
}
throw err;
}
}
function bindings_init() {
if (runtimeHelpers.diagnostic_tracing)
console.debug("MONO_WASM: bindings_init");
if (runtimeHelpers.mono_wasm_bindings_is_ready) {
return;
}
runtimeHelpers.mono_wasm_bindings_is_ready = true;
try {
// please keep System.Runtime.InteropServices.JavaScript.JSHostImplementation.MappedType in sync
Object.prototype[wasm_type_symbol] = 0;
Array.prototype[wasm_type_symbol] = 1;
ArrayBuffer.prototype[wasm_type_symbol] = 2;
DataView.prototype[wasm_type_symbol] = 3;
Function.prototype[wasm_type_symbol] = 4;
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 = 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");
runtimeHelpers.bind_runtime_method = bind_runtime_method;
const bindingAssembly = INTERNAL$1.BINDING_ASM;
const binding_fqn_asm = bindingAssembly.substring(bindingAssembly.indexOf("[") + 1, bindingAssembly.indexOf("]")).trim();
const binding_fqn_class = bindingAssembly.substring(bindingAssembly.indexOf("]") + 1).trim();
const binding_module = wrapped_c_functions.mono_wasm_assembly_load(binding_fqn_asm);
if (!binding_module)
throw "Can't find bindings module assembly: " + binding_fqn_asm;
if (binding_fqn_class && binding_fqn_class.length) {
runtimeHelpers.runtime_interop_exports_classname = binding_fqn_class;
if (binding_fqn_class.indexOf(".") != -1) {
const idx = binding_fqn_class.lastIndexOf(".");
runtimeHelpers.runtime_interop_namespace = binding_fqn_class.substring(0, idx);
runtimeHelpers.runtime_interop_exports_classname = binding_fqn_class.substring(idx + 1);
}
}
runtimeHelpers.runtime_interop_exports_class = wrapped_c_functions.mono_wasm_assembly_find_class(binding_module, runtimeHelpers.runtime_interop_namespace, runtimeHelpers.runtime_interop_exports_classname);
if (!runtimeHelpers.runtime_interop_exports_class)
throw "Can't find " + binding_fqn_class + " class";
runtimeHelpers.get_call_sig_ref = get_method("GetCallSignatureRef");
if (!runtimeHelpers.get_call_sig_ref)
throw "Can't find GetCallSignatureRef method";
runtimeHelpers.complete_task_method = get_method("CompleteTask");
if (!runtimeHelpers.complete_task_method)
throw "Can't find CompleteTask method";
runtimeHelpers.create_task_method = get_method("CreateTaskCallback");
if (!runtimeHelpers.create_task_method)
throw "Can't find CreateTaskCallback method";
runtimeHelpers.call_delegate = get_method("CallDelegate");
if (!runtimeHelpers.call_delegate)
throw "Can't find CallDelegate method";
initialize_marshalers_to_js();
initialize_marshalers_to_cs();
_create_primitive_converters();
runtimeHelpers._box_root = mono_wasm_new_root();
runtimeHelpers._null_root = mono_wasm_new_root();
}
catch (err) {
_print_error("MONO_WASM: Error in bindings_init", err);
throw err;
}
}
function downloadResource(request) {
if (typeof Module.downloadResource === "function") {
return Module.downloadResource(request);
}
const options = {};
if (request.hash) {
options.integrity = request.hash;
}
const response = runtimeHelpers.fetch_like(request.resolvedUrl, options);
return {
name: request.name, url: request.resolvedUrl, response
};
}
async function start_asset_download(asset) {
// we don't addRunDependency to allow download in parallel with onRuntimeInitialized event!
if (asset.buffer) {
++downloded_assets_count;
const buffer = asset.buffer;
asset.buffer = undefined; //GC later
asset.pending = {
url: "undefined://" + asset.name,
name: asset.name,
response: Promise.resolve({
arrayBuffer: () => buffer,
headers: {
get: () => undefined,
}
})
};
return Promise.resolve(asset);
}
if (asset.pending) {
++downloded_assets_count;
return asset;
}
while (throttling_promise) {
await throttling_promise;
}
++parallel_count;
if (parallel_count == max_parallel_downloads) {
if (runtimeHelpers.diagnostic_tracing)
console.debug("MONO_WASM: Throttling further parallel downloads");
throttling_promise = new Promise((resolve) => {
throttling_promise_resolve = resolve;
});
}
const sourcesList = asset.load_remote && config.remote_sources ? config.remote_sources : [""];
let error = undefined;
let result = undefined;
for (let sourcePrefix of sourcesList) {
sourcePrefix = sourcePrefix.trim();
// HACK: Special-case because MSBuild doesn't allow "" as an attribute
if (sourcePrefix === "./")
sourcePrefix = "";
let attemptUrl;
if (!asset.resolvedUrl) {
if (sourcePrefix === "") {
if (asset.behavior === "assembly" || asset.behavior === "pdb")
attemptUrl = config.assembly_root + "/" + asset.name;
else if (asset.behavior === "resource") {
const path = asset.culture !== "" ? `${asset.culture}/${asset.name}` : asset.name;
attemptUrl = config.assembly_root + "/" + path;
}
else
attemptUrl = asset.name;
}
else {
attemptUrl = sourcePrefix + asset.name;
}
attemptUrl = runtimeHelpers.locateFile(attemptUrl);
}
else {
attemptUrl = asset.resolvedUrl;
}
if (asset.name === attemptUrl) {
if (runtimeHelpers.diagnostic_tracing)
console.debug(`MONO_WASM: Attempting to download '${attemptUrl}'`);
}
else {
if (runtimeHelpers.diagnostic_tracing)
console.debug(`MONO_WASM: Attempting to download '${attemptUrl}' for ${asset.name}`);
}
try {
const loadingResource = downloadResource({
name: asset.name,
resolvedUrl: attemptUrl,
hash: asset.hash,
behavior: asset.behavior
});
const response = await loadingResource.response;
if (!response.ok) {
error = new Error(`MONO_WASM: download '${attemptUrl}' for ${asset.name} failed ${response.status} ${response.statusText}`);
continue; // next source
}
asset.pending = loadingResource;
result = asset;
++downloded_assets_count;
error = undefined;
}
catch (err) {
error = new Error(`MONO_WASM: download '${attemptUrl}' for ${asset.name} failed ${err}`);
continue; //next source
}
if (!error) {
break; // this source worked, stop searching
}
}
--parallel_count;
if (throttling_promise && parallel_count == ((max_parallel_downloads / 2) | 0)) {
if (runtimeHelpers.diagnostic_tracing)
console.debug("MONO_WASM: Resuming more parallel downloads");
throttling_promise_resolve();
throttling_promise = undefined;
}
if (error) {
const isOkToFail = asset.is_optional || (asset.name.match(/\.pdb$/) && config.ignore_pdb_load_errors);
if (!isOkToFail)
throw error;
}
return result;
}
async function mono_download_assets() {
if (runtimeHelpers.diagnostic_tracing)
console.debug("MONO_WASM: mono_download_assets");
try {
const asset_promises = [];
// start fetching and instantiating all assets in parallel
for (const asset of config.assets || []) {
if (asset.behavior != "dotnetwasm") {
const downloadedAsset = await start_asset_download(asset);
if (downloadedAsset) {
asset_promises.push((async () => {
const url = downloadedAsset.pending.url;
const response = await downloadedAsset.pending.response;
downloadedAsset.pending = undefined; //GC
const buffer = await response.arrayBuffer();
await beforeOnRuntimeInitialized.promise;
// this is after onRuntimeInitialized
_instantiate_asset(downloadedAsset, url, new Uint8Array(buffer));
})());
}
}
}
// this await will get past the onRuntimeInitialized because we are not blocking via addRunDependency
// and we are not awating it here
all_assets_loaded_in_memory = Promise.all(asset_promises);
// OPTIMIZATION explained:
// we do it this way so that we could allocate memory immediately after asset is downloaded (and after onRuntimeInitialized which happened already)
// spreading in time
// rather than to block all downloads after onRuntimeInitialized or block onRuntimeInitialized after all downloads are done. That would create allocation burst.
}
catch (err) {
Module.printErr("MONO_WASM: Error in mono_download_assets: " + err);
throw err;
}
}
// used from Blazor
function mono_wasm_load_data_archive(data, prefix) {
if (data.length < 8)
return false;
const dataview = new DataView(data.buffer);
const magic = dataview.getUint32(0, true);
// get magic number
if (magic != 0x626c6174) {
return false;
}
const manifestSize = dataview.getUint32(4, true);
if (manifestSize == 0 || data.length < manifestSize + 8)
return false;
let manifest;
try {
const manifestContent = Module.UTF8ArrayToString(data, 8, manifestSize);
manifest = JSON.parse(manifestContent);
if (!(manifest instanceof Array))
return false;
}
catch (exc) {
return false;
}
data = data.slice(manifestSize + 8);
// Create the folder structure
// /usr/share/zoneinfo
// /usr/share/zoneinfo/Africa
// /usr/share/zoneinfo/Asia
// ..
const folders = new Set();
manifest.filter(m => {
const file = m[0];
const last = file.lastIndexOf("/");
const directory = file.slice(0, last + 1);
folders.add(directory);
});
folders.forEach(folder => {
Module["FS_createPath"](prefix, folder, true, true);
});
for (const row of manifest) {
const name = row[0];
const length = row[1];
const bytes = data.slice(0, length);
Module["FS_createDataFile"](prefix, name, bytes, true, true);
data = data.slice(length);
}
return true;
}
let configLoaded = false;
/**
* 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
*/
async function mono_wasm_load_config(configFilePath) {
if (configLoaded) {
return;
}
if (runtimeHelpers.diagnostic_tracing)
console.debug("MONO_WASM: mono_wasm_load_config");
try {
const resolveSrc = runtimeHelpers.locateFile(configFilePath);
const configResponse = await runtimeHelpers.fetch_like(resolveSrc);
const configData = (await configResponse.json()) || {};
// merge
configData.assets = [...(config.assets || []), ...(configData.assets || [])];
config = runtimeHelpers.config = Module.config = Object.assign(Module.config, configData);
// normalize
config.environment_variables = config.environment_variables || {};
config.assets = config.assets || [];
config.runtime_options = config.runtime_options || [];
config.globalization_mode = config.globalization_mode || "auto";
if (config.enable_debugging)
config.debug_level = config.enable_debugging;
if (typeof (config.environment_variables) !== "object")
throw new Error("Expected config.environment_variables to be unset or a dictionary-style object");
if (Module.onConfigLoaded) {
try {
await Module.onConfigLoaded(runtimeHelpers.config);
}
catch (err) {
_print_error("MONO_WASM: onConfigLoaded() failed", err);
throw err;
}
}
runtimeHelpers.diagnostic_tracing = !!runtimeHelpers.config.diagnostic_tracing;
runtimeHelpers.enable_debugging = runtimeHelpers.config.enable_debugging ? runtimeHelpers.config.enable_debugging : 0;
configLoaded = true;
}
catch (err) {
const errMessage = `Failed to load config file ${configFilePath} ${err}`;
abort_startup(errMessage, true);
config = runtimeHelpers.config = Module.config = { message: errMessage, error: err, isError: true };
throw err;
}
}
function mono_wasm_asm_loaded(assembly_name, assembly_ptr, assembly_len, pdb_ptr, pdb_len) {
// Only trigger this codepath for assemblies loaded after app is ready
if (runtimeHelpers.mono_wasm_runtime_is_ready !== true)
return;
const assembly_name_str = assembly_name !== CharPtrNull ? Module.UTF8ToString(assembly_name).concat(".dll") : "";
const assembly_data = new Uint8Array(Module.HEAPU8.buffer, assembly_ptr, assembly_len);
const assembly_b64 = toBase64StringImpl(assembly_data);
let pdb_b64;
if (pdb_ptr) {
const pdb_data = new Uint8Array(Module.HEAPU8.buffer, pdb_ptr, pdb_len);
pdb_b64 = toBase64StringImpl(pdb_data);
}
mono_wasm_raise_debug_event({
eventName: "AssemblyLoaded",
assembly_name: assembly_name_str,
assembly_b64,
pdb_b64
});
}
function mono_wasm_set_main_args(name, allRuntimeArguments) {
const main_argc = allRuntimeArguments.length + 1;
const main_argv = Module._malloc(main_argc * 4);
let aindex = 0;
Module.setValue(main_argv + (aindex * 4), wrapped_c_functions.mono_wasm_strdup(name), "i32");
aindex += 1;
for (let i = 0; i < allRuntimeArguments.length; ++i) {
Module.setValue(main_argv + (aindex * 4), wrapped_c_functions.mono_wasm_strdup(allRuntimeArguments[i]), "i32");
aindex += 1;
}
wrapped_c_functions.mono_wasm_set_main_args(main_argc, main_argv);
}
/// Called when dotnet.worker.js receives an emscripten "load" event from the main thread.
///
/// Notes:
/// 1. Emscripten skips a lot of initialization on the pthread workers, Module may not have everything you expect.
/// 2. Emscripten does not run the preInit or preRun functions in the workers.
/// 3. At the point when this executes there is no pthread assigned to the worker yet.
async function mono_wasm_pthread_worker_init() {
// This is a good place for subsystems to attach listeners for pthreads_worker.currentWorkerThreadEvents
currentWorkerThreadEvents.addEventListener(dotnetPthreadCreated, (ev) => {
console.debug("MONO_WASM: pthread created", ev.pthread_self.pthread_id);
});
}
/**
* @deprecated
*/
async function mono_load_runtime_and_bcl_args(cfg) {
config = Module.config = runtimeHelpers.config = Object.assign(runtimeHelpers.config || {}, cfg || {});
await mono_download_assets();
await all_assets_loaded_in_memory;
}
// Licensed to the .NET Foundation under one or more agreements.
let spread_timers_maximum = 0;
let isChromium = false;
let pump_count = 0;
if (globalThis.navigator) {
const nav = globalThis.navigator;
if (nav.userAgentData && nav.userAgentData.brands) {
isChromium = nav.userAgentData.brands.some((i) => i.brand == "Chromium");
}
else if (nav.userAgent) {
isChromium = nav.userAgent.includes("Chrome");
}
}
function pump_message() {
while (pump_count > 0) {
--pump_count;
wrapped_c_functions.mono_background_exec();
}
}
function prevent_timer_throttling() {
if (!isChromium) {
return;
}
// this will schedule timers every second for next 6 minutes, it should be called from WebSocket event, to make it work
// on next call, it would only extend the timers to cover yet uncovered future
const now = new Date().valueOf();
const desired_reach_time = now + (1000 * 60 * 6);
const next_reach_time = Math.max(now + 1000, spread_timers_maximum);
const light_throttling_frequency = 1000;
for (let schedule = next_reach_time; schedule < desired_reach_time; schedule += light_throttling_frequency) {
const delay = schedule - now;
setTimeout(() => {
wrapped_c_functions.mono_set_timeout_exec();
pump_count++;
pump_message();
}, delay);
}
spread_timers_maximum = desired_reach_time;
}
function schedule_background_exec() {
++pump_count;
setTimeout(pump_message, 0);
}
let lastScheduledTimeoutId = undefined;
function mono_set_timeout(timeout) {
function mono_wasm_set_timeout_exec() {
wrapped_c_functions.mono_set_timeout_exec();
}
if (lastScheduledTimeoutId) {
clearTimeout(lastScheduledTimeoutId);
lastScheduledTimeoutId = undefined;
}
lastScheduledTimeoutId = setTimeout(mono_wasm_set_timeout_exec, timeout);
}
var monoDiagnosticsMock = true;
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
let magic_buf = null;
const Magic = {
get DOTNET_IPC_V1() {
if (magic_buf === null) {
const magic = "DOTNET_IPC_V1";
const magic_len = magic.length + 1; // nul terminated
magic_buf = new Uint8Array(magic_len);
for (let i = 0; i < magic_len; i++) {
magic_buf[i] = magic.charCodeAt(i);
}
magic_buf[magic_len - 1] = 0;
}
return magic_buf;
},
get MinimalHeaderSize() {
// we just need to see the magic and the size
const sizeOfSize = 2;
return Magic.DOTNET_IPC_V1.byteLength + sizeOfSize;
},
};
// Licensed to the .NET Foundation under one or more agreements.
function advancePos$1(pos, count) {
pos.pos += count;
}
function serializeHeader(buf, pos, commandSet, command, len) {
Serializer.serializeMagic(buf, pos);
Serializer.serializeUint16(buf, pos, len);
Serializer.serializeUint8(buf, pos, commandSet);
Serializer.serializeUint8(buf, pos, command);
Serializer.serializeUint16(buf, pos, 0); // reserved
}
const Serializer = {
computeMessageByteLength(payload) {
const fullHeaderSize = Magic.MinimalHeaderSize // magic, len
+ 2 // commandSet, command
+ 2; // reserved ;
const payloadLength = payload ? (payload instanceof Uint8Array ? payload.byteLength : payload) : 0;
const len = fullHeaderSize + payloadLength; // magic, size, commandSet, command, reserved
return len;
},
serializeMagic(buf, pos) {
buf.set(Magic.DOTNET_IPC_V1, pos.pos);
advancePos$1(pos, Magic.DOTNET_IPC_V1.byteLength);
},
serializeUint8(buf, pos, value) {
buf[pos.pos++] = value;
},
serializeUint16(buf, pos, value) {
buf[pos.pos++] = value & 0xFF;
buf[pos.pos++] = (value >> 8) & 0xFF;
},
serializeUint32(buf, pos, value) {
buf[pos.pos++] = value & 0xFF;
buf[pos.pos++] = (value >> 8) & 0xFF;
buf[pos.pos++] = (value >> 16) & 0xFF;
buf[pos.pos++] = (value >> 24) & 0xFF;
},
serializeUint64(buf, pos, value) {
Serializer.serializeUint32(buf, pos, value[0]);
Serializer.serializeUint32(buf, pos, value[1]);
},
serializeHeader,
serializePayload(buf, pos, payload) {
buf.set(payload, pos.pos);
advancePos$1(pos, payload.byteLength);
},
serializeString(buf, pos, s) {
if (s === null) {
Serializer.serializeUint32(buf, pos, 0);
}
else {
const len = s.length;
const hasNul = s[len - 1] === "\0";
Serializer.serializeUint32(buf, pos, len + (hasNul ? 0 : 1));
for (let i = 0; i < len; i++) {
Serializer.serializeUint16(buf, pos, s.charCodeAt(i));
}
if (!hasNul) {
Serializer.serializeUint16(buf, pos, 0);
}
}
},
};
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
/// Make a promise that resolves after a given number of milliseconds.
function delay(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
// Licensed to the .NET Foundation under one or more agreements.
function expectAdvertise(data) {
if (typeof (data) === "string") {
assertNever(data);
}
else {
const view = new Uint8Array(data);
const ADVR_V1 = Array.from("ADVR_V1\0").map((c) => c.charCodeAt(0));
/* TODO: check that the message is really long enough for the cookie, process ID and reserved bytes */
return view.length >= ADVR_V1.length && ADVR_V1.every((v, i) => v === view[i]);
}
}
function expectOk(payloadLength) {
return (data) => {
if (typeof (data) === "string") {
assertNever(data);
}
else {
const view = new Uint8Array(data);
const extra = payloadLength !== undefined ? payloadLength : 0;
return view.length >= (20 + extra) && view[16] === 0xFF && view[17] == 0x00;
}
};
}
function extractOkSessionID(data) {
if (typeof (data) === "string") {
assertNever(data);
}
else {
const view = new Uint8Array(data, 20, 8);
const sessionIDLo = view[0] | (view[1] << 8) | (view[2] << 16) | (view[3] << 24);
const sessionIDHi = view[4] | (view[5] << 8) | (view[6] << 16) | (view[7] << 24);
if (!(sessionIDHi === 0)) throw new Error("Assert failed: mock: sessionIDHi should be zero"); // inlined mono_assert
return sessionIDLo;
}
}
function computeStringByteLength(s) {
if (s === undefined || s === null || s === "")
return 4; // just length of zero
return 4 + 2 * s.length + 2; // length + UTF16 + null
}
function computeCollectTracing2PayloadByteLength(payload) {
let len = 0;
len += 4; // circularBufferMB
len += 4; // format
len += 1; // requestRundown
len += 4; // providers length
for (const provider of payload.providers) {
len += 8; // keywords
len += 4; // level
len += computeStringByteLength(provider.provider_name);
len += computeStringByteLength(provider.filter_data);
}
return len;
}
function makeEventPipeCollectTracing2(payload) {
const payloadLength = computeCollectTracing2PayloadByteLength(payload);
const messageLength = Serializer.computeMessageByteLength(payloadLength);
const buffer = new Uint8Array(messageLength);
const pos = { pos: 0 };
Serializer.serializeHeader(buffer, pos, 2 /* CommandSetId.EventPipe */, 3 /* EventPipeCommandId.CollectTracing2 */, messageLength);
Serializer.serializeUint32(buffer, pos, payload.circularBufferMB);
Serializer.serializeUint32(buffer, pos, payload.format);
Serializer.serializeUint8(buffer, pos, payload.requestRundown ? 1 : 0);
Serializer.serializeUint32(buffer, pos, payload.providers.length);
for (const provider of payload.providers) {
Serializer.serializeUint64(buffer, pos, provider.keywords);
Serializer.serializeUint32(buffer, pos, provider.logLevel);
Serializer.serializeString(buffer, pos, provider.provider_name);
Serializer.serializeString(buffer, pos, provider.filter_data);
}
return buffer;
}
function makeEventPipeStopTracing(payload) {
const payloadLength = 8;
const messageLength = Serializer.computeMessageByteLength(payloadLength);
const buffer = new Uint8Array(messageLength);
const pos = { pos: 0 };
Serializer.serializeHeader(buffer, pos, 2 /* CommandSetId.EventPipe */, 1 /* EventPipeCommandId.StopTracing */, messageLength);
Serializer.serializeUint32(buffer, pos, payload.sessionID);
Serializer.serializeUint32(buffer, pos, 0);
return buffer;
}
function makeProcessResumeRuntime() {
const payloadLength = 0;
const messageLength = Serializer.computeMessageByteLength(payloadLength);
const buffer = new Uint8Array(messageLength);
const pos = { pos: 0 };
Serializer.serializeHeader(buffer, pos, 4 /* CommandSetId.Process */, 1 /* ProcessCommandId.ResumeRuntime */, messageLength);
return buffer;
}
function createMockEnvironment() {
const command = {
makeEventPipeCollectTracing2,
makeEventPipeStopTracing,
makeProcessResumeRuntime,
};
const reply = {
expectOk,
extractOkSessionID,
};
return {
createPromiseController,
delay,
command,
reply,
expectAdvertise
};
}
// Licensed to the .NET Foundation under one or more agreements.
let MockImplConstructor;
function mock(script, options) {
if (monoDiagnosticsMock) {
if (!MockImplConstructor) {
class MockScriptEngineSocketImpl {
constructor(engine) {
this.engine = engine;
}
send(data) {
if (this.engine.trace) {
console.debug(`mock ${this.engine.ident} client sent: `, data);
}
let event = null;
if (typeof data === "string") {
event = new MessageEvent("message", { data });
}
else {
const message = new ArrayBuffer(data.byteLength);
const messageView = new Uint8Array(message);
const dataView = new Uint8Array(data);
messageView.set(dataView);
event = new MessageEvent("message", { data: message });
}
this.engine.mockReplyEventTarget.dispatchEvent(event);
}
addEventListener(event, listener, options) {
if (this.engine.trace) {
console.debug(`mock ${this.engine.ident} client added listener for ${event}`);
}
this.engine.eventTarget.addEventListener(event, listener, options);
}
removeEventListener(event, listener) {
if (this.engine.trace) {
console.debug(`mock ${this.engine.ident} client removed listener for ${event}`);
}
this.engine.eventTarget.removeEventListener(event, listener);
}
close() {
if (this.engine.trace) {
console.debug(`mock ${this.engine.ident} client closed`);
}
this.engine.mockReplyEventTarget.dispatchEvent(new CloseEvent("close"));
}
dispatchEvent(ev) {
return this.engine.eventTarget.dispatchEvent(ev);
}
}
class MockScriptEngineImpl {
constructor(trace, ident) {
this.trace = trace;
this.ident = ident;
// eventTarget that the MockReplySocket will dispatch to
this.eventTarget = new EventTarget();
// eventTarget that the MockReplySocket with send() to
this.mockReplyEventTarget = new EventTarget();
this.socket = new MockScriptEngineSocketImpl(this);
}
reply(data) {
if (this.trace) {
console.debug(`mock ${this.ident} reply:`, data);
}
let sendData;
if (typeof data === "object" && data instanceof ArrayBuffer) {
sendData = new ArrayBuffer(data.byteLength);
const sendDataView = new Uint8Array(sendData);
const dataView = new Uint8Array(data);
sendDataView.set(dataView);
}
else if (typeof data === "object" && data instanceof Uint8Array) {
sendData = new ArrayBuffer(data.byteLength);
const sendDataView = new Uint8Array(sendData);
sendDataView.set(data);
}
else {
console.warn(`mock ${this.ident} reply got wrong kind of reply data, expected ArrayBuffer`, data);
assertNever(data);
}
this.eventTarget.dispatchEvent(new MessageEvent("message", { data: sendData }));
}
async waitForSend(filter, extract) {
const trace = this.trace;
if (trace) {
console.debug(`mock ${this.ident} waitForSend`);
}
const event = await new Promise((resolve) => {
this.mockReplyEventTarget.addEventListener("message", (event) => {
if (trace) {
console.debug(`mock ${this.ident} waitForSend got:`, event);
}
resolve(event);
}, { once: true });
});
const data = event.data;
if (typeof data === "string") {
console.warn(`mock ${this.ident} waitForSend got string:`, data);
throw new Error("mock script connection received string data");
}
if (!filter(data)) {
throw new Error("Unexpected data");
}
if (extract) {
return extract(data);
}
return undefined;
}
}
MockImplConstructor = class MockImpl {
constructor(mockScript, options) {
var _a;
this.mockScript = mockScript;
const env = createMockEnvironment();
this.connectionScripts = mockScript(env);
this.openCount = 0;
this.trace = (_a = options === null || options === void 0 ? void 0 : options.trace) !== null && _a !== void 0 ? _a : false;
const count = this.connectionScripts.length;
this.engines = new Array(count);
for (let i = 0; i < count; ++i) {
this.engines[i] = new MockScriptEngineImpl(this.trace, i);
}
}
open() {
const i = this.openCount++;
if (this.trace) {
console.debug(`mock ${i} open`);
}
return this.engines[i].socket;
}
async run() {
const scripts = this.connectionScripts;
await Promise.all(scripts.map((script, i) => script(this.engines[i])));
}
};
}
return new MockImplConstructor(script, options);
}
else {
return undefined;
}
}
// Licensed to the .NET Foundation under one or more agreements.
function importAndInstantiateMock(mockURL) {
if (monoDiagnosticsMock) {
const mockPrefix = "mock:";
const scriptURL = mockURL.substring(mockPrefix.length);
// revisit this if we ever have a need to mock using CJS, for now we just support ESM
return import(scriptURL).then((mockModule) => {
const script = mockModule.default;
return mock(script, { trace: true });
});
}
else {
return Promise.resolve(undefined);
}
}
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
function isDiagnosticCommandBase(x) {
return typeof x === "object" && "command_set" in x && "command" in x;
}
function isProcessCommand(x) {
return isDiagnosticCommandBase(x) && x.command_set === "Process";
}
function isEventPipeCommand(x) {
return isDiagnosticCommandBase(x) && x.command_set === "EventPipe";
}
function isProcessCommandResumeRuntime(x) {
return isProcessCommand(x) && x.command === "ResumeRuntime";
}
function isEventPipeCollectTracingCommandProvider(x) {
return typeof x === "object" && "keywords" in x && "logLevel" in x && "provider_name" in x && "filter_data" in x;
}
function isEventPipeCommandCollectTracing2(x) {
return isEventPipeCommand(x) && x.command === "CollectTracing2" && "circularBufferMB" in x &&
"format" in x && "requestRundown" in x && "providers" in x &&
Array.isArray(x.providers) && x.providers.every(isEventPipeCollectTracingCommandProvider);
}
function isEventPipeCommandStopTracing(x) {
return isEventPipeCommand(x) && x.command === "StopTracing" && "sessionID" in x;
}
// Licensed to the .NET Foundation under one or more agreements.
var ListenerState;
(function (ListenerState) {
ListenerState[ListenerState["Sending"] = 0] = "Sending";
ListenerState[ListenerState["Closed"] = 1] = "Closed";
ListenerState[ListenerState["Error"] = 2] = "Error";
})(ListenerState || (ListenerState = {}));
class SocketGuts {
constructor(socket) {
this.socket = socket;
}
close() {
this.socket.close();
}
write(data, size) {
const buf = new ArrayBuffer(size);
const view = new Uint8Array(buf);
// Can we avoid this copy?
view.set(new Uint8Array(Module.HEAPU8.buffer, data, size));
this.socket.send(buf);
}
}
/// A wrapper around a WebSocket that just sends data back to the host.
/// It sets up message and clsoe handlers on the WebSocket tht put it into an idle state
/// if the connection closes or we receive any replies.
class EventPipeSocketConnection {
constructor(socket) {
this._state = ListenerState.Sending;
this.stream = new SocketGuts(socket);
}
close() {
console.debug("MONO_WASM: EventPipe session stream closing websocket");
switch (this._state) {
case ListenerState.Error:
return;
case ListenerState.Closed:
return;
default:
this._state = ListenerState.Closed;
this.stream.close();
return;
}
}
write(ptr, len) {
switch (this._state) {
case ListenerState.Sending:
this.stream.write(ptr, len);
return true;
case ListenerState.Closed:
// ignore
return false;
case ListenerState.Error:
return false;
}
}
_onMessage(event) {
switch (this._state) {
case ListenerState.Sending:
/* unexpected message */
console.warn("MONO_WASM: EventPipe session stream received unexpected message from websocket", event);
// TODO notify runtime that the connection had an error
this._state = ListenerState.Error;
break;
case ListenerState.Closed:
/* ignore */
break;
case ListenerState.Error:
/* ignore */
break;
default:
assertNever(this._state);
}
}
_onClose( /*event: CloseEvent*/) {
switch (this._state) {
case ListenerState.Closed:
return; /* do nothing */
case ListenerState.Error:
return; /* do nothing */
default:
this._state = ListenerState.Closed;
this.stream.close();
// TODO: notify runtime that connection is closed
return;
}
}
_onError(event) {
console.debug("MONO_WASM: EventPipe session stream websocket error", event);
this._state = ListenerState.Error;
this.stream.close();
// TODO: notify runtime that connection had an error
}
addListeners() {
const socket = this.stream.socket;
socket.addEventListener("message", this._onMessage.bind(this));
addEventListener("close", this._onClose.bind(this));
addEventListener("error", this._onError.bind(this));
}
}
/// Take over a WebSocket that was used by the diagnostic server to receive the StartCollecting command and
/// use it for sending the event pipe data back to the host.
function takeOverSocket(socket) {
const connection = new EventPipeSocketConnection(socket);
connection.addListeners();
return connection;
}
// Licensed to the .NET Foundation under one or more agreements.
/// One-reader, one-writer, size 1 queue for messages from an EventPipe streaming thread to
// the diagnostic server thread that owns the WebSocket.
// EventPipeStreamQueue has 3 memory words that are used to communicate with the streaming thread:
// struct MonoWasmEventPipeStreamQueue {
// union { void* buf; intptr_t close_msg; /* -1 */ };
// int32_t count;
// volatile int32_t buf_full;
// }
//
// To write, the streaming thread:
// 1. sets buf (or close_msg) and count, and then atomically sets buf_full.
// 2. queues mono_wasm_diagnostic_server_stream_signal_work_available to run on the diagnostic server thread
// 3. waits for buf_full to be 0.
//
// Note this is a little bit fragile if there are multiple writers.
// There _are_ multiple writers - when the streaming session first starts, either the diagnostic server thread
// or the main thread write to the queue before the streaming thread starts. But those actions are
// implicitly serialized because the streaming thread isn't started until the writes are done.
const BUF_OFFSET = 0;
const COUNT_OFFSET = 4;
const WRITE_DONE_OFFSET = 8;
const STREAM_CLOSE_SENTINEL = -1;
class StreamQueue {
constructor(queue_addr, syncSendBuffer, syncSendClose) {
this.queue_addr = queue_addr;
this.syncSendBuffer = syncSendBuffer;
this.syncSendClose = syncSendClose;
this.workAvailable = new EventTarget();
this.signalWorkAvailable = this.signalWorkAvailableImpl.bind(this);
this.workAvailable.addEventListener("workAvailable", this.onWorkAvailable.bind(this));
}
get buf_addr() {
return this.queue_addr + BUF_OFFSET;
}
get count_addr() {
return this.queue_addr + COUNT_OFFSET;
}
get buf_full_addr() {
return this.queue_addr + WRITE_DONE_OFFSET;
}
/// called from native code on the diagnostic thread when the streaming thread queues a call to notify the
/// diagnostic thread that it can send the buffer.
wakeup() {
queueMicrotask(this.signalWorkAvailable);
}
workAvailableNow() {
// process the queue immediately, rather than waiting for the next event loop tick.
this.onWorkAvailable();
}
signalWorkAvailableImpl() {
this.workAvailable.dispatchEvent(new Event("workAvailable"));
}
onWorkAvailable() {
const buf = getI32(this.buf_addr);
const intptr_buf = buf;
if (intptr_buf === STREAM_CLOSE_SENTINEL) {
// special value signaling that the streaming thread closed the queue.
this.syncSendClose();
}
else {
const count = getI32(this.count_addr);
setI32(this.buf_addr, 0);
if (count > 0) {
this.syncSendBuffer(buf, count);
}
}
/* buffer is now not full */
Atomics$1.storeI32(this.buf_full_addr, 0);
/* wake up the writer thread */
Atomics$1.notifyI32(this.buf_full_addr, 1);
}
}
// maps stream queue addresses to StreamQueue instances
const streamQueueMap = new Map();
function allocateQueue(nativeQueueAddr, syncSendBuffer, syncSendClose) {
const queue = new StreamQueue(nativeQueueAddr, syncSendBuffer, syncSendClose);
streamQueueMap.set(nativeQueueAddr, queue);
return queue;
}
function closeQueue(nativeQueueAddr) {
streamQueueMap.delete(nativeQueueAddr);
// TODO: remove the event listener?
}
// called from native code on the diagnostic thread by queueing a call from the streaming thread.
function mono_wasm_diagnostic_server_stream_signal_work_available(nativeQueueAddr, current_thread) {
const queue = streamQueueMap.get(nativeQueueAddr);
if (queue) {
if (current_thread === 0) {
queue.wakeup();
}
else {
queue.workAvailableNow();
}
}
}
/// The streaming session holds all the pieces of an event pipe streaming session that the
/// diagnostic server knows about: the session ID, a
/// queue used by the EventPipe streaming thread to forward events to the diagnostic server thread,
/// and a wrapper around the WebSocket object used to send event data back to the host.
class EventPipeStreamingSession {
constructor(sessionID, queue, connection) {
this.sessionID = sessionID;
this.queue = queue;
this.connection = connection;
}
}
async function makeEventPipeStreamingSession(ws, cmd) {
// First, create the native IPC stream and get its queue.
const ipcStreamAddr = wrapped_c_functions.mono_wasm_diagnostic_server_create_stream(); // FIXME: this should be a wrapped in a JS object so we can free it when we're done.
const queueAddr = getQueueAddrFromStreamAddr(ipcStreamAddr);
// then take over the websocket connection
const conn = takeOverSocket(ws);
// and set up queue notifications
const queue = allocateQueue(queueAddr, conn.write.bind(conn), conn.close.bind(conn));
const options = {
rundownRequested: cmd.requestRundown,
bufferSizeInMB: cmd.circularBufferMB,
providers: providersStringFromObject(cmd.providers),
};
// create the event pipe session
const sessionID = createEventPipeStreamingSession(ipcStreamAddr, options);
if (sessionID === false)
throw new Error("failed to create event pipe session");
return new EventPipeStreamingSession(sessionID, queue, conn);
}
function providersStringFromObject(providers) {
const providersString = providers.map(providerToString).join(",");
return providersString;
function providerToString(provider) {
const keyword_str = provider.keywords[0] === 0 && provider.keywords[1] === 0 ? "" : keywordsToHexString(provider.keywords);
const args_str = provider.filter_data === "" ? "" : ":" + provider.filter_data;
return provider.provider_name + ":" + keyword_str + ":" + provider.logLevel + args_str;
}
function keywordsToHexString(k) {
const lo = k[0];
const hi = k[1];
const lo_hex = lo.toString(16);
const hi_hex = hi.toString(16);
return hi_hex + lo_hex;
}
}
const IPC_STREAM_QUEUE_OFFSET = 4; /* keep in sync with mono_wasm_diagnostic_server_create_stream() in C */
function getQueueAddrFromStreamAddr(streamAddr) {
return streamAddr + IPC_STREAM_QUEUE_OFFSET;
}
// Licensed to the .NET Foundation under one or more agreements.
function advancePos(pos, offset) {
pos.pos += offset;
}
const Parser = {
tryParseHeader(buf, pos) {
let j = pos.pos;
for (let i = 0; i < Magic.DOTNET_IPC_V1.length; i++) {
if (buf[j++] !== Magic.DOTNET_IPC_V1[i]) {
return false;
}
}
advancePos(pos, Magic.DOTNET_IPC_V1.length);
return true;
},
tryParseSize(buf, pos) {
return Parser.tryParseUint16(buf, pos);
},
tryParseCommand(buf, pos) {
const commandSet = Parser.tryParseUint8(buf, pos);
if (commandSet === undefined)
return undefined;
const command = Parser.tryParseUint8(buf, pos);
if (command === undefined)
return undefined;
if (Parser.tryParseReserved(buf, pos) === undefined)
return undefined;
const payload = buf.slice(pos.pos);
const result = {
commandSet,
command,
payload
};
return result;
},
tryParseReserved(buf, pos) {
const reservedLength = 2; // 2 bytes reserved, must be 0
for (let i = 0; i < reservedLength; i++) {
const reserved = Parser.tryParseUint8(buf, pos);
if (reserved === undefined || reserved !== 0) {
return undefined;
}
}
return true;
},
tryParseUint8(buf, pos) {
const j = pos.pos;
if (j >= buf.byteLength) {
return undefined;
}
const size = buf[j];
advancePos(pos, 1);
return size;
},
tryParseUint16(buf, pos) {
const j = pos.pos;
if (j + 1 >= buf.byteLength) {
return undefined;
}
const size = (buf[j + 1] << 8) | buf[j];
advancePos(pos, 2);
return size;
},
tryParseUint32(buf, pos) {
const j = pos.pos;
if (j + 3 >= buf.byteLength) {
return undefined;
}
const size = (buf[j + 3] << 24) | (buf[j + 2] << 16) | (buf[j + 1] << 8) | buf[j];
advancePos(pos, 4);
return size;
},
tryParseUint64(buf, pos) {
const lo = Parser.tryParseUint32(buf, pos);
if (lo === undefined)
return undefined;
const hi = Parser.tryParseUint32(buf, pos);
if (hi === undefined)
return undefined;
return [lo, hi];
},
tryParseBool(buf, pos) {
const r = Parser.tryParseUint8(buf, pos);
if (r === undefined)
return undefined;
return r !== 0;
},
tryParseArraySize(buf, pos) {
const r = Parser.tryParseUint32(buf, pos);
if (r === undefined)
return undefined;
return r;
},
tryParseStringLength(buf, pos) {
return Parser.tryParseArraySize(buf, pos);
},
tryParseUtf16String(buf, pos) {
const length = Parser.tryParseStringLength(buf, pos);
if (length === undefined)
return undefined;
const j = pos.pos;
if (j + length * 2 > buf.byteLength) {
return undefined;
}
const result = new Array(length);
for (let i = 0; i < length; i++) {
result[i] = (buf[j + 2 * i + 1] << 8) | buf[j + 2 * i];
}
advancePos(pos, length * 2);
return String.fromCharCode.apply(null, result);
}
};
// Licensed to the .NET Foundation under one or more agreements.
const dotnetDiagnosticsServerProtocolCommandEvent = "dotnet:diagnostics:protocolCommand";
var InState;
(function (InState) {
InState[InState["Idle"] = 0] = "Idle";
InState[InState["PartialCommand"] = 1] = "PartialCommand";
InState[InState["Error"] = 2] = "Error";
})(InState || (InState = {}));
/// A helper object that accumulates command data that is received and provides parsed commands
class StatefulParser {
constructor(emitCommandCallback) {
this.emitCommandCallback = emitCommandCallback;
this.state = { state: InState.Idle };
}
/// process the data in the given buffer and update the state.
receiveBuffer(buf) {
if (this.state.state == InState.Error) {
return;
}
let result;
if (this.state.state === InState.Idle) {
result = this.tryParseHeader(new Uint8Array(buf));
}
else {
result = this.tryAppendBuffer(new Uint8Array(buf));
}
if (result.success) {
console.debug("MONO_WASM: protocol-socket: got result", result);
this.setState(result.newState);
if (result.command) {
const command = result.command;
this.emitCommandCallback(command);
}
}
else {
console.warn("MONO_WASM: socket received invalid command header", buf, result.error);
// FIXME: dispatch error event?
this.setState({ state: InState.Error });
}
}
tryParseHeader(buf) {
const pos = { pos: 0 };
if (buf.byteLength < Magic.MinimalHeaderSize) {
// TODO: we need to see the magic and the size to make a partial commmand
return { success: false, error: "not enough data" };
}
if (!Parser.tryParseHeader(buf, pos)) {
return { success: false, error: "invalid header" };
}
const size = Parser.tryParseSize(buf, pos);
if (size === undefined || size < Magic.MinimalHeaderSize) {
return { success: false, error: "invalid size" };
}
// make a "partially completed" state with a buffer of the right size and just the header upto the size
// field filled in.
const parsedSize = pos.pos;
const partialBuf = new ArrayBuffer(size);
const partialBufView = new Uint8Array(partialBuf);
partialBufView.set(buf.subarray(0, parsedSize));
const partialState = { state: InState.PartialCommand, buf: partialBufView, size: parsedSize };
return this.continueWithBuffer(partialState, buf.subarray(parsedSize));
}
tryAppendBuffer(moreBuf) {
if (this.state.state !== InState.PartialCommand) {
return { success: false, error: "not in partial command state" };
}
return this.continueWithBuffer(this.state, moreBuf);
}
continueWithBuffer(state, moreBuf) {
const buf = state.buf;
let partialSize = state.size;
let overflow = null;
if (partialSize + moreBuf.byteLength <= buf.byteLength) {
buf.set(moreBuf, partialSize);
partialSize += moreBuf.byteLength;
}
else {
const overflowSize = partialSize + moreBuf.byteLength - buf.byteLength;
const overflowOffset = moreBuf.byteLength - overflowSize;
buf.set(moreBuf.subarray(0, buf.byteLength - partialSize), partialSize);
partialSize = buf.byteLength;
const overflowBuf = new ArrayBuffer(overflowSize);
overflow = new Uint8Array(overflowBuf);
overflow.set(moreBuf.subarray(overflowOffset));
}
if (partialSize < buf.byteLength) {
const newState = { state: InState.PartialCommand, buf, size: partialSize };
return { success: true, command: undefined, newState };
}
else {
const pos = { pos: Magic.MinimalHeaderSize };
let result = this.tryParseCompletedBuffer(buf, pos);
if (overflow) {
console.warn("MONO_WASM: additional bytes past command payload", overflow);
if (result.success) {
const newResult = { success: true, command: result.command, newState: { state: InState.Error } };
result = newResult;
}
}
return result;
}
}
tryParseCompletedBuffer(buf, pos) {
const command = Parser.tryParseCommand(buf, pos);
if (!command) {
this.setState({ state: InState.Error });
return { success: false, error: "invalid command" };
}
return { success: true, command, newState: { state: InState.Idle } };
}
setState(state) {
this.state = state;
}
reset() {
this.setState({ state: InState.Idle });
}
}
class ProtocolSocketImpl {
constructor(sock) {
this.sock = sock;
this.statefulParser = new StatefulParser(this.emitCommandCallback.bind(this));
this.protocolListeners = 0;
this.messageListener = this.onMessage.bind(this);
}
onMessage(ev) {
const data = ev.data;
console.debug("MONO_WASM: protocol socket received message", ev.data);
if (typeof data === "object" && data instanceof ArrayBuffer) {
this.onArrayBuffer(data);
}
else if (typeof data === "object" && data instanceof Blob) {
data.arrayBuffer().then(this.onArrayBuffer.bind(this));
}
else if (typeof data === "string") {
// otherwise it's string, ignore it.
console.debug("MONO_WASM: protocol socket received string message; ignoring it", ev.data);
}
else {
assertNever(data);
}
}
dispatchEvent(evt) {
return this.sock.dispatchEvent(evt);
}
onArrayBuffer(buf) {
console.debug("MONO_WASM: protocol-socket: parsing array buffer", buf);
this.statefulParser.receiveBuffer(buf);
}
// called by the stateful parser when it has a complete command
emitCommandCallback(command) {
console.debug("MONO_WASM: protocol-socket: queueing command", command);
queueMicrotask(() => {
console.debug("MONO_WASM: dispatching protocol event with command", command);
this.dispatchProtocolCommandEvent(command);
});
}
dispatchProtocolCommandEvent(cmd) {
const ev = new Event(dotnetDiagnosticsServerProtocolCommandEvent);
ev.data = cmd; // FIXME: use a proper event subclass
this.sock.dispatchEvent(ev);
}
addEventListener(type, listener, options) {
this.sock.addEventListener(type, listener, options);
if (type === dotnetDiagnosticsServerProtocolCommandEvent) {
if (this.protocolListeners === 0) {
console.debug("MONO_WASM: adding protocol listener, with a message chaser");
this.sock.addEventListener("message", this.messageListener);
}
this.protocolListeners++;
}
}
removeEventListener(type, listener) {
if (type === dotnetDiagnosticsServerProtocolCommandEvent) {
console.debug("MONO_WASM: removing protocol listener and message chaser");
this.protocolListeners--;
if (this.protocolListeners === 0) {
this.sock.removeEventListener("message", this.messageListener);
this.statefulParser.reset();
}
}
this.sock.removeEventListener(type, listener);
}
send(buf) {
this.sock.send(buf);
}
close() {
this.sock.close();
this.statefulParser.reset();
}
}
function createProtocolSocket(socket) {
return new ProtocolSocketImpl(socket);
}
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
function isBinaryProtocolCommand(x) {
return "commandSet" in x && "command" in x && "payload" in x;
}
// Licensed to the .NET Foundation under one or more agreements.
function parseBinaryProtocolCommand(cmd) {
switch (cmd.commandSet) {
case 0 /* CommandSetId.Reserved */:
throw new Error("unexpected reserved command_set command");
case 1 /* CommandSetId.Dump */:
throw new Error("TODO");
case 2 /* CommandSetId.EventPipe */:
return parseEventPipeCommand(cmd);
case 3 /* CommandSetId.Profiler */:
throw new Error("TODO");
case 4 /* CommandSetId.Process */:
return parseProcessCommand(cmd);
default:
return { success: false, error: `unexpected command_set ${cmd.commandSet} command` };
}
}
function parseEventPipeCommand(cmd) {
switch (cmd.command) {
case 1 /* EventPipeCommandId.StopTracing */:
return parseEventPipeStopTracing(cmd);
case 2 /* EventPipeCommandId.CollectTracing */:
throw new Error("TODO");
case 3 /* EventPipeCommandId.CollectTracing2 */:
return parseEventPipeCollectTracing2(cmd);
default:
console.warn("MONO_WASM: unexpected EventPipe command: " + cmd.command);
return { success: false, error: `unexpected EventPipe command ${cmd.command}` };
}
}
function parseEventPipeCollectTracing2(cmd) {
const pos = { pos: 0 };
const buf = cmd.payload;
const circularBufferMB = Parser.tryParseUint32(buf, pos);
if (circularBufferMB === undefined) {
return { success: false, error: "failed to parse circularBufferMB in EventPipe CollectTracing2 command" };
}
const format = Parser.tryParseUint32(buf, pos);
if (format === undefined) {
return { success: false, error: "failed to parse format in EventPipe CollectTracing2 command" };
}
const requestRundown = Parser.tryParseBool(buf, pos);
if (requestRundown === undefined) {
return { success: false, error: "failed to parse requestRundown in EventPipe CollectTracing2 command" };
}
const numProviders = Parser.tryParseArraySize(buf, pos);
if (numProviders === undefined) {
return { success: false, error: "failed to parse numProviders in EventPipe CollectTracing2 command" };
}
const providers = new Array(numProviders);
for (let i = 0; i < numProviders; i++) {
const result = parseEventPipeCollectTracingCommandProvider(buf, pos);
if (!result.success) {
return result;
}
providers[i] = result.result;
}
const command = { command_set: "EventPipe", command: "CollectTracing2", circularBufferMB, format, requestRundown, providers };
return { success: true, result: command };
}
function parseEventPipeCollectTracingCommandProvider(buf, pos) {
const keywords = Parser.tryParseUint64(buf, pos);
if (keywords === undefined) {
return { success: false, error: "failed to parse keywords in EventPipe CollectTracing provider" };
}
const logLevel = Parser.tryParseUint32(buf, pos);
if (logLevel === undefined)
return { success: false, error: "failed to parse logLevel in EventPipe CollectTracing provider" };
const providerName = Parser.tryParseUtf16String(buf, pos);
if (providerName === undefined)
return { success: false, error: "failed to parse providerName in EventPipe CollectTracing provider" };
const filterData = Parser.tryParseUtf16String(buf, pos);
if (filterData === undefined)
return { success: false, error: "failed to parse filterData in EventPipe CollectTracing provider" };
const provider = { keywords, logLevel, provider_name: providerName, filter_data: filterData };
return { success: true, result: provider };
}
function parseEventPipeStopTracing(cmd) {
const pos = { pos: 0 };
const buf = cmd.payload;
const sessionID = Parser.tryParseUint64(buf, pos);
if (sessionID === undefined) {
return { success: false, error: "failed to parse sessionID in EventPipe StopTracing command" };
}
const [lo, hi] = sessionID;
if (hi !== 0) {
return { success: false, error: "sessionID is too large in EventPipe StopTracing command" };
}
const command = { command_set: "EventPipe", command: "StopTracing", sessionID: lo };
return { success: true, result: command };
}
function parseProcessCommand(cmd) {
switch (cmd.command) {
case 0 /* ProcessCommandId.ProcessInfo */:
throw new Error("TODO");
case 1 /* ProcessCommandId.ResumeRuntime */:
return parseProcessResumeRuntime(cmd);
case 2 /* ProcessCommandId.ProcessEnvironment */:
throw new Error("TODO");
case 4 /* ProcessCommandId.ProcessInfo2 */:
throw new Error("TODO");
default:
console.warn("MMONO_WASM: unexpected Process command: " + cmd.command);
return { success: false, error: `unexpected Process command ${cmd.command}` };
}
}
function parseProcessResumeRuntime(cmd) {
const buf = cmd.payload;
if (buf.byteLength !== 0) {
return { success: false, error: "unexpected payload in Process ResumeRuntime command" };
}
const command = { command_set: "Process", command: "ResumeRuntime" };
return { success: true, result: command };
}
// Licensed to the .NET Foundation under one or more agreements.
function createBinaryCommandOKReply(payload) {
const len = Serializer.computeMessageByteLength(payload);
const buf = new Uint8Array(len);
const pos = { pos: 0 };
Serializer.serializeHeader(buf, pos, 255 /* CommandSetId.Server */, 0 /* ServerCommandId.OK */, len);
if (payload !== undefined) {
Serializer.serializePayload(buf, pos, payload);
}
return buf;
}
function serializeGuid(buf, pos, guid) {
guid.split("-").forEach((part) => {
// FIXME: I'm sure the endianness is wrong here
for (let i = 0; i < part.length; i += 2) {
const idx = part.length - i - 2; // go through the pieces backwards
buf[pos.pos++] = Number.parseInt(part.substring(idx, idx + 2), 16);
}
});
}
function serializeAsciiLiteralString(buf, pos, s) {
const len = s.length;
const hasNul = s[len - 1] === "\0";
for (let i = 0; i < len; i++) {
Serializer.serializeUint8(buf, pos, s.charCodeAt(i));
}
if (!hasNul) {
Serializer.serializeUint8(buf, pos, 0);
}
}
function createAdvertise(guid, processId) {
const BUF_LENGTH = 34;
const buf = new Uint8Array(BUF_LENGTH);
const pos = { pos: 0 };
const advrText = "ADVR_V1\0";
serializeAsciiLiteralString(buf, pos, advrText);
serializeGuid(buf, pos, guid);
Serializer.serializeUint64(buf, pos, processId);
Serializer.serializeUint16(buf, pos, 0); // reserved
if (!(pos.pos == BUF_LENGTH)) throw new Error("Assert failed: did not format ADVR_V1 correctly"); // inlined mono_assert
return buf;
}
// Licensed to the .NET Foundation under one or more agreements.
function addOneShotProtocolCommandEventListener(src) {
return new Promise((resolve) => {
const listener = (event) => { resolve(event); };
src.addEventListener(dotnetDiagnosticsServerProtocolCommandEvent, listener, { once: true });
});
}
function addOneShotOpenEventListenr(src) {
return new Promise((resolve) => {
const listener = (event) => { resolve(event); };
src.addEventListener("open", listener, { once: true });
});
}
class DiagnosticServerImpl {
constructor(websocketUrl, mockPromise) {
this.runtimeResumed = false;
this.startRequestedController = createPromiseController().promise_control;
this.stopRequested = false;
this.stopRequestedController = createPromiseController().promise_control;
this.attachToRuntimeController = createPromiseController().promise_control;
this.openCount = 0;
this.websocketUrl = websocketUrl;
pthread_self.addEventListenerFromBrowser(this.onMessageFromMainThread.bind(this));
this.mocked = monoDiagnosticsMock ? mockPromise : undefined;
}
start() {
console.log(`MONO_WASM: starting diagnostic server with url: ${this.websocketUrl}`);
this.startRequestedController.resolve();
}
stop() {
this.stopRequested = true;
this.stopRequestedController.resolve();
}
attachToRuntime() {
wrapped_c_functions.mono_wasm_diagnostic_server_thread_attach_to_runtime();
this.attachToRuntimeController.resolve();
}
async serverLoop() {
await this.startRequestedController.promise;
await this.attachToRuntimeController.promise; // can't start tracing until we've attached to the runtime
while (!this.stopRequested) {
console.debug("MONO_WASM: diagnostic server: advertising and waiting for client");
const p1 = this.advertiseAndWaitForClient().then(() => "first");
const p2 = this.stopRequestedController.promise.then(() => "second");
const result = await Promise.race([p1, p2]);
switch (result) {
case "first":
break;
case "second":
console.debug("MONO_WASM: stop requested");
break;
default:
assertNever(result);
}
}
}
async openSocket() {
if (monoDiagnosticsMock && this.mocked) {
return (await this.mocked).open();
}
else {
const sock = new WebSocket(this.websocketUrl);
// TODO: add an "error" handler here - if we get readyState === 3, the connection failed.
await addOneShotOpenEventListenr(sock);
return sock;
}
}
async advertiseAndWaitForClient() {
try {
const connNum = this.openCount++;
console.debug("MONO_WASM: opening websocket and sending ADVR_V1", connNum);
const ws = await this.openSocket();
const p = addOneShotProtocolCommandEventListener(createProtocolSocket(ws));
this.sendAdvertise(ws);
const message = await p;
console.debug("MONO_WASM: received advertising response: ", message, connNum);
queueMicrotask(() => this.parseAndDispatchMessage(ws, connNum, message));
}
finally {
// if there were errors, resume the runtime anyway
this.resumeRuntime();
}
}
async parseAndDispatchMessage(ws, connNum, message) {
try {
const cmd = this.parseCommand(message, connNum);
if (cmd === null) {
console.error("MONO_WASM: unexpected message from client", message, connNum);
return;
}
else if (isEventPipeCommand(cmd)) {
await this.dispatchEventPipeCommand(ws, cmd);
}
else if (isProcessCommand(cmd)) {
await this.dispatchProcessCommand(ws, cmd); // resume
}
else {
console.warn("MONO_WASM Client sent unknown command", cmd);
}
}
finally {
// if there were errors, resume the runtime anyway
this.resumeRuntime();
}
}
sendAdvertise(ws) {
/* FIXME: don't use const fake guid and fake process id. In dotnet-dsrouter the pid is used
* as a dictionary key,so if we ever supprt multiple runtimes, this might need to change.
*/
const guid = "C979E170-B538-475C-BCF1-B04A30DA1430";
const processIdLo = 0;
const processIdHi = 1234;
const buf = createAdvertise(guid, [processIdLo, processIdHi]);
ws.send(buf);
}
parseCommand(message, connNum) {
console.debug("MONO_WASM: parsing byte command: ", message.data, connNum);
const result = parseProtocolCommand(message.data);
console.debug("MONO_WASM: parsied byte command: ", result, connNum);
if (result.success) {
return result.result;
}
else {
console.warn("MONO_WASM: failed to parse command: ", result.error, connNum);
return null;
}
}
onMessageFromMainThread(event) {
const d = event.data;
if (d && isDiagnosticMessage(d)) {
this.controlCommandReceived(d);
}
}
/// dispatch commands received from the main thread
controlCommandReceived(cmd) {
switch (cmd.cmd) {
case "start":
this.start();
break;
case "stop":
this.stop();
break;
case "attach_to_runtime":
this.attachToRuntime();
break;
default:
console.warn("MONO_WASM: Unknown control command: ", cmd);
break;
}
}
// dispatch EventPipe commands received from the diagnostic client
async dispatchEventPipeCommand(ws, cmd) {
if (isEventPipeCommandCollectTracing2(cmd)) {
await this.collectTracingEventPipe(ws, cmd);
}
else if (isEventPipeCommandStopTracing(cmd)) {
await this.stopEventPipe(ws, cmd.sessionID);
}
else {
console.warn("MONO_WASM: unknown EventPipe command: ", cmd);
}
}
postClientReplyOK(ws, payload) {
// FIXME: send a binary response for non-mock sessions!
ws.send(createBinaryCommandOKReply(payload));
}
async stopEventPipe(ws, sessionID) {
console.debug("MONO_WASM: stopEventPipe", sessionID);
wrapped_c_functions.mono_wasm_event_pipe_session_disable(sessionID);
// we might send OK before the session is actually stopped since the websocket is async
// but the client end should be robust to that.
this.postClientReplyOK(ws);
}
async collectTracingEventPipe(ws, cmd) {
const session = await makeEventPipeStreamingSession(ws, cmd);
const sessionIDbuf = new Uint8Array(8); // 64 bit
sessionIDbuf[0] = session.sessionID & 0xFF;
sessionIDbuf[1] = (session.sessionID >> 8) & 0xFF;
sessionIDbuf[2] = (session.sessionID >> 16) & 0xFF;
sessionIDbuf[3] = (session.sessionID >> 24) & 0xFF;
// sessionIDbuf[4..7] is 0 because all our session IDs are 32-bit
this.postClientReplyOK(ws, sessionIDbuf);
console.debug("MONO_WASM: created session, now streaming: ", session);
wrapped_c_functions.mono_wasm_event_pipe_session_start_streaming(session.sessionID);
}
// dispatch Process commands received from the diagnostic client
async dispatchProcessCommand(ws, cmd) {
if (isProcessCommandResumeRuntime(cmd)) {
this.processResumeRuntime(ws);
}
else {
console.warn("MONO_WASM: unknown Process command", cmd);
}
}
processResumeRuntime(ws) {
this.postClientReplyOK(ws);
this.resumeRuntime();
}
resumeRuntime() {
if (!this.runtimeResumed) {
console.info("MONO_WASM: resuming runtime startup");
wrapped_c_functions.mono_wasm_diagnostic_server_post_resume_runtime();
this.runtimeResumed = true;
}
}
}
function parseProtocolCommand(data) {
if (isBinaryProtocolCommand(data)) {
return parseBinaryProtocolCommand(data);
}
else {
throw new Error("binary blob from mock is not implemented");
}
}
/// Called by the runtime to initialize the diagnostic server workers
function mono_wasm_diagnostic_server_on_server_thread_created(websocketUrlPtr) {
const websocketUrl = Module.UTF8ToString(websocketUrlPtr);
console.debug(`mono_wasm_diagnostic_server_on_server_thread_created, url ${websocketUrl}`);
let mock = undefined;
if (monoDiagnosticsMock && websocketUrl.startsWith("mock:")) {
mock = createPromiseController();
queueMicrotask(async () => {
const m = await importAndInstantiateMock(websocketUrl);
mock.promise_control.resolve(m);
m.run();
});
}
const server = new DiagnosticServerImpl(websocketUrl, mock === null || mock === void 0 ? void 0 : mock.promise);
queueMicrotask(() => {
server.serverLoop();
});
}
// Licensed to the .NET Foundation under one or more agreements.
function mono_wasm_bind_js_function(function_name, module_name, signature, function_js_handle, is_exception, result_address) {
const function_name_root = mono_wasm_new_external_root(function_name), module_name_root = mono_wasm_new_external_root(module_name), resultRoot = mono_wasm_new_external_root(result_address);
try {
const version = get_signature_version(signature);
if (!(version === 1)) throw new Error(`Assert failed: Signature version ${version} mismatch.`); // inlined mono_assert
const js_function_name = conv_string_root(function_name_root);
const js_module_name = conv_string_root(module_name_root);
if (runtimeHelpers.diagnostic_tracing) {
console.debug(`MONO_WASM: Binding [JSImport] ${js_function_name} from ${js_module_name}`);
}
const fn = mono_wasm_lookup_function(js_function_name, js_module_name);
const args_count = get_signature_argument_count(signature);
const closure = { fn, marshal_exception_to_cs, signature };
const bound_js_function_name = "_bound_js_" + js_function_name.replace(/\./g, "_");
let body = `//# sourceURL=https://mono-wasm.invalid/${bound_js_function_name} \n`;
let converter_names = "";
let bodyToJs = "";
let pass_args = "";
for (let index = 0; index < args_count; index++) {
const arg_offset = (index + 2) * JavaScriptMarshalerArgSize;
const sig_offset = (index + 2) * JSMarshalerTypeSize + JSMarshalerSignatureHeaderSize;
const arg_name = `arg${index}`;
const sig = get_sig(signature, index + 2);
const { converters, call_body } = generate_arg_marshal_to_js(sig, index + 2, arg_offset, sig_offset, arg_name, closure);
converter_names += converters;
bodyToJs += call_body;
if (pass_args === "") {
pass_args += arg_name;
}
else {
pass_args += `, ${arg_name}`;
}
}
const { converters: res_converters, call_body: res_call_body, marshaler_type: res_marshaler_type } = generate_arg_marshal_to_cs(get_sig(signature, 1), 1, JavaScriptMarshalerArgSize, JSMarshalerTypeSize + JSMarshalerSignatureHeaderSize, "js_result", closure);
converter_names += res_converters;
body += `const { signature, fn, marshal_exception_to_cs ${converter_names} } = closure;\n`;
body += `return function ${bound_js_function_name} (args) { try {\n`;
// body += `console.log("${bound_js_function_name}")\n`;
body += bodyToJs;
if (res_marshaler_type === MarshalerType.Void) {
body += ` const js_result = fn(${pass_args});\n`;
body += ` if (js_result !== undefined) throw new Error('Function ${js_function_name} returned unexpected value, C# signature is void');\n`;
}
else if (res_marshaler_type === MarshalerType.Discard) {
body += ` fn(${pass_args});\n`;
}
else {
body += ` const js_result = fn(${pass_args});\n`;
body += res_call_body;
}
for (let index = 0; index < args_count; index++) {
const sig = get_sig(signature, index + 2);
const marshaler_type = get_signature_type(sig);
if (marshaler_type == MarshalerType.Span) {
const arg_name = `arg${index}`;
body += ` ${arg_name}.dispose();\n`;
}
}
body += "} catch (ex) {\n";
body += " marshal_exception_to_cs(args, ex);\n";
body += "}}";
const factory = new Function("closure", body);
const bound_fn = factory(closure);
bound_fn[bound_js_function_symbol] = true;
const bound_function_handle = mono_wasm_get_js_handle(bound_fn);
setI32(function_js_handle, bound_function_handle);
}
catch (ex) {
wrap_error_root(is_exception, ex, resultRoot);
}
finally {
resultRoot.release();
function_name_root.release();
}
}
function mono_wasm_invoke_bound_function(bound_function_js_handle, args) {
const bound_fn = mono_wasm_get_jsobj_from_js_handle(bound_function_js_handle);
if (!(bound_fn && typeof (bound_fn) === "function" && bound_fn[bound_js_function_symbol])) throw new Error(`Assert failed: Bound function handle expected ${bound_function_js_handle}`); // inlined mono_assert
bound_fn(args);
}
function mono_wasm_lookup_function(function_name, js_module_name) {
if (!(function_name && typeof function_name === "string")) throw new Error("Assert failed: function_name must be string"); // inlined mono_assert
let scope = IMPORTS;
const parts = function_name.split(".");
if (js_module_name) {
scope = importedModules.get(js_module_name);
if (!(scope)) throw new Error(`Assert failed: ES6 module ${js_module_name} was not imported yet, please call JSHost.Import() first.`); // inlined mono_assert
}
else if (parts[0] === "INTERNAL") {
scope = INTERNAL$1;
parts.shift();
}
else if (parts[0] === "globalThis") {
scope = globalThis;
parts.shift();
}
for (let i = 0; i < parts.length - 1; i++) {
const part = parts[i];
const newscope = scope[part];
if (!(newscope)) throw new Error(`Assert failed: ${part} not found while looking up ${function_name}`); // inlined mono_assert
scope = newscope;
}
const fname = parts[parts.length - 1];
const fn = scope[fname];
if (!(typeof (fn) === "function")) throw new Error(`Assert failed: ${function_name} must be a Function but was ${typeof fn}`); // inlined mono_assert
// if the function was already bound to some object it would stay bound to original object. That's good.
return fn.bind(scope);
}
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
function set_property(self, name, value) {
if (!(self)) throw new Error("Assert failed: Null reference"); // inlined mono_assert
self[name] = value;
}
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
function get_property(self, name) {
if (!(self)) throw new Error("Assert failed: Null reference"); // inlined mono_assert
return self[name];
}
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
function has_property(self, name) {
if (!(self)) throw new Error("Assert failed: Null reference"); // inlined mono_assert
return name in self;
}
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
function get_typeof_property(self, name) {
if (!(self)) throw new Error("Assert failed: Null reference"); // inlined mono_assert
return typeof self[name];
}
function get_global_this() {
return globalThis;
}
const importedModulesPromises = new Map();
const importedModules = new Map();
async function dynamic_import(module_name, module_url) {
if (!(module_name)) throw new Error("Assert failed: Invalid module_name"); // inlined mono_assert
if (!(module_url)) throw new Error("Assert failed: Invalid module_name"); // inlined mono_assert
let promise = importedModulesPromises.get(module_name);
const newPromise = !promise;
if (newPromise) {
if (runtimeHelpers.diagnostic_tracing)
console.debug(`MONO_WASM: importing ES6 module '${module_name}' from '${module_url}'`);
promise = import(/* webpackIgnore: true */ module_url);
importedModulesPromises.set(module_name, promise);
}
const module = await promise;
if (newPromise) {
importedModules.set(module_name, module);
if (runtimeHelpers.diagnostic_tracing)
console.debug(`MONO_WASM: imported ES6 module '${module_name}' from '${module_url}'`);
}
return module;
}
// Licensed to the .NET Foundation under one or more agreements.
const exportedMethods = new Map();
function mono_wasm_bind_cs_function(fully_qualified_name, signature_hash, signature, is_exception, result_address) {
const fqn_root = mono_wasm_new_external_root(fully_qualified_name), resultRoot = mono_wasm_new_external_root(result_address);
const anyModule = Module;
try {
const version = get_signature_version(signature);
if (!(version === 1)) throw new Error(`Assert failed: Signature version ${version} mismatch.`); // inlined mono_assert
const args_count = get_signature_argument_count(signature);
const js_fqn = conv_string_root(fqn_root);
if (!(js_fqn)) throw new Error("Assert failed: fully_qualified_name must be string"); // inlined mono_assert
if (runtimeHelpers.diagnostic_tracing) {
console.debug(`MONO_WASM: Binding [JSExport] ${js_fqn}`);
}
const { assembly, namespace, classname, methodname } = parseFQN(js_fqn);
const asm = assembly_load(assembly);
if (!asm)
throw new Error("Could not find assembly: " + assembly);
const klass = wrapped_c_functions.mono_wasm_assembly_find_class(asm, namespace, classname);
if (!klass)
throw new Error("Could not find class: " + namespace + ":" + classname + " in assembly " + assembly);
const wrapper_name = `__Wrapper_${methodname}_${signature_hash}`;
const method = find_method(klass, wrapper_name, -1);
if (!method)
throw new Error(`Could not find method: ${wrapper_name} in ${klass} [${assembly}]`);
const closure = {
method, get_arg, signature,
stackSave: anyModule.stackSave, stackAlloc: anyModule.stackAlloc, stackRestore: anyModule.stackRestore,
conv_string,
mono_wasm_new_root, init_void, init_result, /*init_argument,*/ marshal_exception_to_js, is_args_exception,
mono_wasm_invoke_method_bound: wrap_c_function("mono_wasm_invoke_method_bound"),
};
const bound_js_function_name = "_bound_cs_" + `${namespace}_${classname}_${methodname}`.replace(/\./g, "_").replace(/\//g, "_");
let body = `//# sourceURL=https://mono-wasm.invalid/${bound_js_function_name} \n`;
let bodyToCs = "";
let converter_names = "";
for (let index = 0; index < args_count; index++) {
const arg_offset = (index + 2) * JavaScriptMarshalerArgSize;
const sig_offset = (index + 2) * JSMarshalerTypeSize + JSMarshalerSignatureHeaderSize;
const sig = get_sig(signature, index + 2);
const { converters, call_body } = generate_arg_marshal_to_cs(sig, index + 2, arg_offset, sig_offset, `arguments[${index}]`, closure);
converter_names += converters;
bodyToCs += call_body;
}
const { converters: res_converters, call_body: res_call_body, marshaler_type: res_marshaler_type } = generate_arg_marshal_to_js(get_sig(signature, 1), 1, JavaScriptMarshalerArgSize, JSMarshalerTypeSize + JSMarshalerSignatureHeaderSize, "js_result", closure);
converter_names += res_converters;
body += `const { method, get_arg, signature, stackSave, stackAlloc, stackRestore, mono_wasm_new_root, conv_string, init_void, init_result, init_argument, marshal_exception_to_js, is_args_exception, mono_wasm_invoke_method_bound ${converter_names} } = closure;\n`;
// TODO named arguments instead of arguments keyword
body += `return function ${bound_js_function_name} () {\n`;
if (res_marshaler_type === MarshalerType.String) {
body += "let root = null;\n";
}
body += "const sp = stackSave();\n";
body += "try {\n";
body += ` const args = stackAlloc(${(args_count + 2) * JavaScriptMarshalerArgSize});\n`;
if (res_marshaler_type !== MarshalerType.Void && res_marshaler_type !== MarshalerType.Discard) {
if (res_marshaler_type === MarshalerType.String) {
body += " root = mono_wasm_new_root(0);\n";
body += " init_result(args);\n";
}
else {
body += " init_result(args);\n";
}
}
else {
body += " init_void(args);\n";
}
body += bodyToCs;
body += " const fail = mono_wasm_invoke_method_bound(method, args);\n";
body += " if (fail) throw new Error(\"ERR22: Unexpected error: \" + conv_string(fail));\n";
body += " if (is_args_exception(args)) throw marshal_exception_to_js(get_arg(args, 0));\n";
if (res_marshaler_type !== MarshalerType.Void && res_marshaler_type !== MarshalerType.Discard) {
body += res_call_body;
}
if (res_marshaler_type !== MarshalerType.Void && res_marshaler_type !== MarshalerType.Discard) {
body += "return js_result;\n";
}
body += "} finally {\n";
body += " stackRestore(sp);\n";
if (res_marshaler_type === MarshalerType.String) {
body += " if(root) root.release()\n";
}
body += "}}";
const factory = new Function("closure", body);
const bound_fn = factory(closure);
bound_fn[bound_cs_function_symbol] = true;
exportedMethods.set(js_fqn, bound_fn);
_walk_exports_to_set_function(assembly, namespace, classname, methodname, signature_hash, bound_fn);
}
catch (ex) {
Module.printErr(ex.toString());
wrap_error_root(is_exception, ex, resultRoot);
}
finally {
resultRoot.release();
fqn_root.release();
}
}
function init_void(args) {
if (!(args && args % 8 == 0)) throw new Error("Assert failed: Arg alignment"); // inlined mono_assert
const exc = get_arg(args, 0);
set_arg_type(exc, MarshalerType.None);
const res = get_arg(args, 1);
set_arg_type(res, MarshalerType.None);
}
function init_result(args) {
if (!(args && args % 8 == 0)) throw new Error("Assert failed: Arg alignment"); // inlined mono_assert
const exc = get_arg(args, 0);
set_arg_type(exc, MarshalerType.None);
const res = get_arg(args, 1);
set_arg_type(res, MarshalerType.None);
}
const exportsByAssembly = new Map();
function _walk_exports_to_set_function(assembly, namespace, classname, methodname, signature_hash, fn) {
let scope = EXPORTS;
const parts = `${namespace}.${classname}`.replace(/\//g, ".").split(".");
for (let i = 0; i < parts.length; i++) {
const part = parts[i];
if (part != "") {
let newscope = scope[part];
if (typeof newscope === "undefined") {
newscope = {};
scope[part] = newscope;
}
if (!(newscope)) throw new Error(`Assert failed: ${part} not found while looking up ${classname}`); // inlined mono_assert
scope = newscope;
}
}
if (!scope[methodname]) {
scope[methodname] = fn;
}
scope[`${methodname}.${signature_hash}`] = fn;
// do it again for per assemly scope
let assemblyScope = exportsByAssembly.get(assembly);
if (!assemblyScope) {
assemblyScope = {};
exportsByAssembly.set(assembly, assemblyScope);
exportsByAssembly.set(assembly + ".dll", assemblyScope);
}
scope = assemblyScope;
for (let i = 0; i < parts.length; i++) {
const part = parts[i];
if (part != "") {
let newscope = scope[part];
if (typeof newscope === "undefined") {
newscope = {};
scope[part] = newscope;
}
if (!(newscope)) throw new Error(`Assert failed: ${part} not found while looking up ${classname}`); // inlined mono_assert
scope = newscope;
}
}
if (!scope[methodname]) {
scope[methodname] = fn;
}
scope[`${methodname}.${signature_hash}`] = fn;
}
async function mono_wasm_get_assembly_exports(assembly) {
if (!(runtimeHelpers.mono_wasm_bindings_is_ready)) throw new Error("Assert failed: Expected binding to be initialized later during startup sequence."); // inlined mono_assert
const asm = assembly_load(assembly);
if (!asm)
throw new Error("Could not find assembly: " + assembly);
wrapped_c_functions.mono_wasm_runtime_run_module_cctor(asm);
return exportsByAssembly.get(assembly) || {};
}
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
class Queue {
constructor() {
this.queue = [];
this.offset = 0;
}
// initialise the queue and offset
// Returns the length of the queue.
getLength() {
return (this.queue.length - this.offset);
}
// Returns true if the queue is empty, and false otherwise.
isEmpty() {
return (this.queue.length == 0);
}
/* Enqueues the specified item. The parameter is:
*
* item - the item to enqueue
*/
enqueue(item) {
this.queue.push(item);
}
/* Dequeues an item and returns it. If the queue is empty, the value
* 'undefined' is returned.
*/
dequeue() {
// if the queue is empty, return immediately
if (this.queue.length === 0)
return undefined;
// store the item at the front of the queue
const item = this.queue[this.offset];
// for GC's sake
this.queue[this.offset] = null;
// increment the offset and remove the free space if necessary
if (++this.offset * 2 >= this.queue.length) {
this.queue = this.queue.slice(this.offset);
this.offset = 0;
}
// return the dequeued item
return item;
}
/* Returns the item at the front of the queue (without dequeuing it). If the
* queue is empty then undefined is returned.
*/
peek() {
return (this.queue.length > 0 ? this.queue[this.offset] : undefined);
}
drain(onEach) {
while (this.getLength()) {
const item = this.dequeue();
onEach(item);
}
}
}
// Licensed to the .NET Foundation under one or more agreements.
const wasm_ws_pending_send_buffer = Symbol.for("wasm ws_pending_send_buffer");
const wasm_ws_pending_send_buffer_offset = Symbol.for("wasm ws_pending_send_buffer_offset");
const wasm_ws_pending_send_buffer_type = Symbol.for("wasm ws_pending_send_buffer_type");
const wasm_ws_pending_receive_event_queue = Symbol.for("wasm ws_pending_receive_event_queue");
const wasm_ws_pending_receive_promise_queue = Symbol.for("wasm ws_pending_receive_promise_queue");
const wasm_ws_pending_open_promise = Symbol.for("wasm ws_pending_open_promise");
const wasm_ws_pending_close_promises = Symbol.for("wasm ws_pending_close_promises");
const wasm_ws_pending_send_promises = Symbol.for("wasm ws_pending_send_promises");
const wasm_ws_is_aborted = Symbol.for("wasm ws_is_aborted");
let mono_wasm_web_socket_close_warning = false;
let _text_decoder_utf8 = undefined;
let _text_encoder_utf8 = undefined;
const ws_send_buffer_blocking_threshold = 65536;
const emptyBuffer = new Uint8Array();
function ws_wasm_create(uri, sub_protocols, onClosed) {
if (!(uri && typeof uri === "string")) throw new Error(`Assert failed: ERR12: Invalid uri ${typeof uri}`); // inlined mono_assert
const ws = new globalThis.WebSocket(uri, sub_protocols || undefined);
const { promise_control: open_promise_control } = createPromiseController();
ws[wasm_ws_pending_receive_event_queue] = new Queue();
ws[wasm_ws_pending_receive_promise_queue] = new Queue();
ws[wasm_ws_pending_open_promise] = open_promise_control;
ws[wasm_ws_pending_send_promises] = [];
ws[wasm_ws_pending_close_promises] = [];
ws.binaryType = "arraybuffer";
const local_on_open = () => {
if (ws[wasm_ws_is_aborted])
return;
open_promise_control.resolve(ws);
prevent_timer_throttling();
};
const local_on_message = (ev) => {
if (ws[wasm_ws_is_aborted])
return;
_mono_wasm_web_socket_on_message(ws, ev);
prevent_timer_throttling();
};
const local_on_close = (ev) => {
ws.removeEventListener("message", local_on_message);
if (ws[wasm_ws_is_aborted])
return;
if (onClosed)
onClosed(ev.code, ev.reason);
// this reject would not do anything if there was already "open" before it.
open_promise_control.reject(ev.reason);
for (const close_promise_control of ws[wasm_ws_pending_close_promises]) {
close_promise_control.resolve();
}
// send close to any pending receivers, to wake them
const receive_promise_queue = ws[wasm_ws_pending_receive_promise_queue];
receive_promise_queue.drain((receive_promise_control) => {
const response = new Int32Array([
0,
2,
1
]); // end_of_message: true
receive_promise_control.responseView.set(response);
receive_promise_control.resolve();
});
};
const local_on_error = (ev) => {
open_promise_control.reject(ev.message || "WebSocket error");
};
ws.addEventListener("message", local_on_message);
ws.addEventListener("open", local_on_open, { once: true });
ws.addEventListener("close", local_on_close, { once: true });
ws.addEventListener("error", local_on_error, { once: true });
return ws;
}
function ws_wasm_open(ws) {
if (!(!!ws)) throw new Error("Assert failed: ERR17: expected ws instance"); // inlined mono_assert
const open_promise_control = ws[wasm_ws_pending_open_promise];
return open_promise_control.promise;
}
function ws_wasm_send(ws, bufferView, message_type, end_of_message) {
if (!(!!ws)) throw new Error("Assert failed: ERR17: expected ws instance"); // inlined mono_assert
const whole_buffer = _mono_wasm_web_socket_send_buffering(ws, bufferView, message_type, end_of_message);
if (!end_of_message || !whole_buffer) {
return null;
}
return _mono_wasm_web_socket_send_and_wait(ws, whole_buffer, bufferView);
}
function ws_wasm_receive(ws, bufferView, responseView) {
if (!(!!ws)) throw new Error("Assert failed: ERR18: expected ws instance"); // inlined mono_assert
const receive_event_queue = ws[wasm_ws_pending_receive_event_queue];
const receive_promise_queue = ws[wasm_ws_pending_receive_promise_queue];
const readyState = ws.readyState;
if (readyState != WebSocket.OPEN && readyState != WebSocket.CLOSING) {
throw new Error("InvalidState: The WebSocket is not connected.");
}
if (receive_event_queue.getLength()) {
if (!(receive_promise_queue.getLength() == 0)) throw new Error("Assert failed: ERR20: Invalid WS state"); // inlined mono_assert
// finish synchronously
_mono_wasm_web_socket_receive_buffering(receive_event_queue, bufferView, responseView);
return null;
}
const { promise, promise_control } = createPromiseController();
const receive_promise_control = promise_control;
receive_promise_control.bufferView = bufferView;
receive_promise_control.responseView = responseView;
receive_promise_queue.enqueue(receive_promise_control);
return promise;
}
function ws_wasm_close(ws, code, reason, wait_for_close_received) {
if (!(!!ws)) throw new Error("Assert failed: ERR19: expected ws instance"); // inlined mono_assert
if (ws.readyState == WebSocket.CLOSED) {
return null;
}
if (wait_for_close_received) {
const { promise, promise_control } = createPromiseController();
ws[wasm_ws_pending_close_promises].push(promise_control);
if (typeof reason === "string") {
ws.close(code, reason);
}
else {
ws.close(code);
}
return promise;
}
else {
if (!mono_wasm_web_socket_close_warning) {
mono_wasm_web_socket_close_warning = true;
console.warn("WARNING: Web browsers do not support closing the output side of a WebSocket. CloseOutputAsync has closed the socket and discarded any incoming messages.");
}
if (typeof reason === "string") {
ws.close(code, reason);
}
else {
ws.close(code);
}
return null;
}
}
function ws_wasm_abort(ws) {
if (!(!!ws)) throw new Error("Assert failed: ERR18: expected ws instance"); // inlined mono_assert
ws[wasm_ws_is_aborted] = true;
const open_promise_control = ws[wasm_ws_pending_open_promise];
if (open_promise_control) {
open_promise_control.reject("OperationCanceledException");
}
for (const close_promise_control of ws[wasm_ws_pending_close_promises]) {
close_promise_control.reject("OperationCanceledException");
}
for (const send_promise_control of ws[wasm_ws_pending_send_promises]) {
send_promise_control.reject("OperationCanceledException");
}
ws[wasm_ws_pending_receive_promise_queue].drain(receive_promise_control => {
receive_promise_control.reject("OperationCanceledException");
});
// this is different from Managed implementation
ws.close(1000, "Connection was aborted.");
}
function _mono_wasm_web_socket_send_and_wait(ws, buffer, managedBuffer) {
// send and return promise
ws.send(buffer);
managedBuffer.dispose();
ws[wasm_ws_pending_send_buffer] = null;
// if the remaining send buffer is small, we don't block so that the throughput doesn't suffer.
// Otherwise we block so that we apply some backpresure to the application sending large data.
// this is different from Managed implementation
if (ws.bufferedAmount < ws_send_buffer_blocking_threshold) {
return null;
}
// block the promise/task until the browser passed the buffer to OS
const { promise, promise_control } = createPromiseController();
const pending = ws[wasm_ws_pending_send_promises];
pending.push(promise_control);
let nextDelay = 1;
const polling_check = () => {
// was it all sent yet ?
if (ws.bufferedAmount === 0) {
promise_control.resolve();
}
else if (ws.readyState != WebSocket.OPEN) {
// only reject if the data were not sent
// bufferedAmount does not reset to zero once the connection closes
promise_control.reject("InvalidState: The WebSocket is not connected.");
}
else if (!promise_control.isDone) {
globalThis.setTimeout(polling_check, nextDelay);
// exponentially longer delays, up to 1000ms
nextDelay = Math.min(nextDelay * 1.5, 1000);
return;
}
// remove from pending
const index = pending.indexOf(promise_control);
if (index > -1) {
pending.splice(index, 1);
}
};
globalThis.setTimeout(polling_check, 0);
return promise;
}
function _mono_wasm_web_socket_on_message(ws, event) {
const event_queue = ws[wasm_ws_pending_receive_event_queue];
const promise_queue = ws[wasm_ws_pending_receive_promise_queue];
if (typeof event.data === "string") {
if (_text_encoder_utf8 === undefined) {
_text_encoder_utf8 = new TextEncoder();
}
event_queue.enqueue({
type: 0,
// according to the spec https://encoding.spec.whatwg.org/
// - Unpaired surrogates will get replaced with 0xFFFD
// - utf8 encode specifically is defined to never throw
data: _text_encoder_utf8.encode(event.data),
offset: 0
});
}
else {
if (event.data.constructor.name !== "ArrayBuffer") {
throw new Error("ERR19: WebSocket receive expected ArrayBuffer");
}
event_queue.enqueue({
type: 1,
data: new Uint8Array(event.data),
offset: 0
});
}
if (promise_queue.getLength() && event_queue.getLength() > 1) {
throw new Error("ERR21: Invalid WS state"); // assert
}
while (promise_queue.getLength() && event_queue.getLength()) {
const promise_control = promise_queue.dequeue();
_mono_wasm_web_socket_receive_buffering(event_queue, promise_control.bufferView, promise_control.responseView);
promise_control.resolve();
}
prevent_timer_throttling();
}
function _mono_wasm_web_socket_receive_buffering(event_queue, bufferView, responseView) {
const event = event_queue.peek();
const count = Math.min(bufferView.length, event.data.length - event.offset);
if (count > 0) {
const sourceView = event.data.subarray(event.offset, event.offset + count);
bufferView.set(sourceView, 0);
event.offset += count;
}
const end_of_message = event.data.length === event.offset ? 1 : 0;
if (end_of_message) {
event_queue.dequeue();
}
const response = new Int32Array([count, event.type, end_of_message]);
responseView.set(response);
bufferView.dispose();
responseView.dispose();
}
function _mono_wasm_web_socket_send_buffering(ws, bufferView, message_type, end_of_message) {
let buffer = ws[wasm_ws_pending_send_buffer];
let offset = 0;
const length = bufferView.length;
if (buffer) {
offset = ws[wasm_ws_pending_send_buffer_offset];
// match desktop WebSocket behavior by copying message_type of the first part
message_type = ws[wasm_ws_pending_send_buffer_type];
// if not empty message, append to existing buffer
if (length !== 0) {
if (offset + length > buffer.length) {
const newbuffer = new Uint8Array((offset + length + 50) * 1.5); // exponential growth
newbuffer.set(buffer, 0); // copy previous buffer
bufferView.copyTo(newbuffer.subarray(offset)); // append copy at the end
ws[wasm_ws_pending_send_buffer] = buffer = newbuffer;
}
else {
bufferView.copyTo(buffer.subarray(offset)); // append copy at the end
}
offset += length;
ws[wasm_ws_pending_send_buffer_offset] = offset;
}
}
else if (!end_of_message) {
// create new buffer
if (length !== 0) {
buffer = bufferView.slice(); // copy
offset = length;
ws[wasm_ws_pending_send_buffer_offset] = offset;
ws[wasm_ws_pending_send_buffer] = buffer;
}
ws[wasm_ws_pending_send_buffer_type] = message_type;
}
else {
if (length !== 0) {
// we could use the unsafe view, because it will be immediately used in ws.send()
buffer = bufferView._unsafe_create_view();
offset = length;
}
}
// buffer was updated, do we need to trim and convert it to final format ?
if (end_of_message) {
if (offset == 0 || buffer == null) {
return emptyBuffer;
}
if (message_type === 0) {
// text, convert from UTF-8 bytes to string, because of bad browser API
if (_text_decoder_utf8 === undefined) {
// we do not validate outgoing data https://github.com/dotnet/runtime/issues/59214
_text_decoder_utf8 = new TextDecoder("utf-8", { fatal: false });
}
// See https://github.com/whatwg/encoding/issues/172
const bytes = typeof SharedArrayBuffer !== "undefined" && buffer instanceof SharedArrayBuffer
? buffer.slice(0, offset)
: buffer.subarray(0, offset);
return _text_decoder_utf8.decode(bytes);
}
else {
// binary, view to used part of the buffer
return buffer.subarray(0, offset);
}
}
return null;
}
// Licensed to the .NET Foundation under one or more agreements.
function http_wasm_supports_streaming_response() {
return typeof Response !== "undefined" && "body" in Response.prototype && typeof ReadableStream === "function";
}
function http_wasm_create_abort_controler() {
return new AbortController();
}
function http_wasm_abort_request(abort_controller) {
abort_controller.abort();
}
function http_wasm_abort_response(res) {
res.__abort_controller.abort();
if (res.__reader) {
res.__reader.cancel();
}
}
function http_wasm_fetch_bytes(url, header_names, header_values, option_names, option_values, abort_controller, bodyPtr, bodyLength) {
// the bufferPtr is pinned by the caller
const view = new Span(bodyPtr, bodyLength, 0 /* MemoryViewType.Byte */);
const copy = view.slice();
return http_wasm_fetch(url, header_names, header_values, option_names, option_values, abort_controller, copy);
}
function http_wasm_fetch(url, header_names, header_values, option_names, option_values, abort_controller, body) {
if (!(url && typeof url === "string")) throw new Error("Assert failed: expected url string"); // inlined mono_assert
if (!(header_names && header_values && Array.isArray(header_names) && Array.isArray(header_values) && header_names.length === header_values.length)) throw new Error("Assert failed: expected headerNames and headerValues arrays"); // inlined mono_assert
if (!(option_names && option_values && Array.isArray(option_names) && Array.isArray(option_values) && option_names.length === option_values.length)) throw new Error("Assert failed: expected headerNames and headerValues arrays"); // inlined mono_assert
const headers = new Headers();
for (let i = 0; i < header_names.length; i++) {
headers.append(header_names[i], header_values[i]);
}
const options = {
body,
headers,
signal: abort_controller.signal
};
for (let i = 0; i < option_names.length; i++) {
options[option_names[i]] = option_values[i];
}
return wrap_as_cancelable_promise(async () => {
const res = await fetch(url, options);
res.__abort_controller = abort_controller;
return res;
});
}
function get_response_headers(res) {
if (!res.__headerNames) {
res.__headerNames = [];
res.__headerValues = [];
const entries = res.headers.entries();
for (const pair of entries) {
res.__headerNames.push(pair[0]);
res.__headerValues.push(pair[1]);
}
}
}
function http_wasm_get_response_header_names(res) {
get_response_headers(res);
return res.__headerNames;
}
function http_wasm_get_response_header_values(res) {
get_response_headers(res);
return res.__headerValues;
}
function http_wasm_get_response_length(res) {
return wrap_as_cancelable_promise(async () => {
const buffer = await res.arrayBuffer();
res.__buffer = buffer;
res.__source_offset = 0;
return buffer.byteLength;
});
}
function http_wasm_get_response_bytes(res, view) {
if (!(res.__buffer)) throw new Error("Assert failed: expected resoved arrayBuffer"); // inlined mono_assert
if (res.__source_offset == res.__buffer.byteLength) {
return 0;
}
const source_view = new Uint8Array(res.__buffer, res.__source_offset);
view.set(source_view, 0);
const bytes_read = Math.min(view.byteLength, source_view.byteLength);
res.__source_offset += bytes_read;
return bytes_read;
}
async function http_wasm_get_streamed_response_bytes(res, bufferPtr, bufferLength) {
// the bufferPtr is pinned by the caller
const view = new Span(bufferPtr, bufferLength, 0 /* MemoryViewType.Byte */);
return wrap_as_cancelable_promise(async () => {
if (!res.__chunk && res.body) {
res.__reader = res.body.getReader();
res.__chunk = await res.__reader.read();
res.__source_offset = 0;
}
let target_offset = 0;
let bytes_read = 0;
// loop until end of browser stream or end of C# buffer
while (res.__reader && res.__chunk && !res.__chunk.done) {
const remaining_source = res.__chunk.value.byteLength - res.__source_offset;
if (remaining_source === 0) {
res.__chunk = await res.__reader.read();
res.__source_offset = 0;
continue; // are we done yet
}
const remaining_target = view.byteLength - target_offset;
const bytes_copied = Math.min(remaining_source, remaining_target);
const source_view = res.__chunk.value.subarray(res.__source_offset, res.__source_offset + bytes_copied);
// copy available bytes
view.set(source_view, target_offset);
target_offset += bytes_copied;
bytes_read += bytes_copied;
res.__source_offset += bytes_copied;
if (target_offset == view.byteLength) {
return bytes_read;
}
}
return bytes_read;
});
}
// Licensed to the .NET Foundation under one or more agreements.
const MONO = {
// current "public" MONO API
mono_wasm_setenv,
mono_wasm_load_bytes_into_heap,
mono_wasm_load_icu_data,
mono_wasm_runtime_ready,
mono_wasm_load_data_archive,
mono_wasm_load_config,
mono_load_runtime_and_bcl_args,
mono_wasm_new_root_buffer,
mono_wasm_new_root,
mono_wasm_new_external_root,
mono_wasm_release_roots,
mono_run_main,
mono_run_main_and_exit,
mono_wasm_get_assembly_exports,
mono_wasm_add_assembly: wrapped_c_functions.mono_wasm_add_assembly,
mono_wasm_load_runtime,
config: runtimeHelpers.config,
loaded_files: [],
// memory accessors
setB32,
setI8,
setI16,
setI32,
setI52,
setU52,
setI64Big,
setU8,
setU16,
setU32,
setF32,
setF64,
getB32,
getI8,
getI16,
getI32,
getI52,
getU52,
getI64Big,
getU8,
getU16,
getU32,
getF32,
getF64,
// Diagnostics
diagnostics
};
const BINDING = {
//current "public" BINDING API
/**
* @deprecated Not GC or thread safe
*/
mono_obj_array_new: wrapped_c_functions.mono_wasm_obj_array_new,
/**
* @deprecated Not GC or thread safe
*/
mono_obj_array_set: wrapped_c_functions.mono_wasm_obj_array_set,
/**
* @deprecated Not GC or thread safe
*/
js_string_to_mono_string,
/**
* @deprecated Not GC or thread safe
*/
js_typed_array_to_array,
/**
* @deprecated Not GC or thread safe
*/
mono_array_to_js_array,
/**
* @deprecated Not GC or thread safe
*/
js_to_mono_obj,
/**
* @deprecated Not GC or thread safe
*/
conv_string,
/**
* @deprecated Not GC or thread safe
*/
unbox_mono_obj,
/**
* @deprecated Renamed to conv_string_root
*/
conv_string_rooted: conv_string_root,
mono_obj_array_new_ref: wrapped_c_functions.mono_wasm_obj_array_new_ref,
mono_obj_array_set_ref: wrapped_c_functions.mono_wasm_obj_array_set_ref,
js_string_to_mono_string_root,
js_typed_array_to_array_root,
js_to_mono_obj_root,
conv_string_root,
unbox_mono_obj_root,
mono_array_root_to_js_array,
bind_static_method: mono_bind_static_method,
call_assembly_entry_point: mono_call_assembly_entry_point,
};
let exportedAPI;
// this is executed early during load of emscripten runtime
// it exports methods to global objects MONO, BINDING and Module in backward compatible way
// At runtime this will be referred to as 'createDotnetRuntime'
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
function initializeImportsAndExports(imports, exports, replacements) {
const module = exports.module;
const globalThisAny = globalThis;
// we want to have same instance of MONO, BINDING and Module in dotnet iffe
set_imports_exports(imports, exports);
init_polyfills(replacements);
// here we merge methods from the local objects into exported objects
Object.assign(exports.mono, MONO);
Object.assign(exports.binding, BINDING);
Object.assign(exports.internal, INTERNAL);
exportedAPI = {
MONO: exports.mono,
BINDING: exports.binding,
INTERNAL: exports.internal,
EXPORTS: exports.marshaled_exports,
IMPORTS: exports.marshaled_imports,
Module: module,
RuntimeBuildInfo: {
ProductVersion,
Configuration
}
};
if (exports.module.__undefinedConfig) {
module.disableDotnet6Compatibility = true;
module.configSrc = "./mono-config.json";
}
if (!module.print) {
module.print = console.log.bind(console);
}
if (!module.printErr) {
module.printErr = console.error.bind(console);
}
if (typeof module.disableDotnet6Compatibility === "undefined") {
module.disableDotnet6Compatibility = imports.isESM;
}
// here we expose objects global namespace for tests and backward compatibility
if (imports.isGlobal || !module.disableDotnet6Compatibility) {
Object.assign(module, exportedAPI);
// backward compatibility
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
module.mono_bind_static_method = (fqn, signature /*ArgsMarshalString*/) => {
console.warn("MONO_WASM: Module.mono_bind_static_method is obsolete, please use BINDING.bind_static_method instead");
return mono_bind_static_method(fqn, signature);
};
const warnWrap = (name, provider) => {
if (typeof globalThisAny[name] !== "undefined") {
// it already exists in the global namespace
return;
}
let value = undefined;
Object.defineProperty(globalThis, name, {
get: () => {
if (is_nullish(value)) {
const stack = (new Error()).stack;
const nextLine = stack ? stack.substr(stack.indexOf("\n", 8) + 1) : "";
console.warn(`MONO_WASM: global ${name} is obsolete, please use Module.${name} instead ${nextLine}`);
value = provider();
}
return value;
}
});
};
globalThisAny.MONO = exports.mono;
globalThisAny.BINDING = exports.binding;
globalThisAny.INTERNAL = exports.internal;
if (!imports.isGlobal) {
globalThisAny.Module = module;
}
// Blazor back compat
warnWrap("cwrap", () => module.cwrap);
warnWrap("addRunDependency", () => module.addRunDependency);
warnWrap("removeRunDependency", () => module.removeRunDependency);
}
// this code makes it possible to find dotnet runtime on a page via global namespace, even when there are multiple runtimes at the same time
let list;
if (!globalThisAny.getDotnetRuntime) {
globalThisAny.getDotnetRuntime = (runtimeId) => globalThisAny.getDotnetRuntime.__list.getRuntime(runtimeId);
globalThisAny.getDotnetRuntime.__list = list = new RuntimeList();
}
else {
list = globalThisAny.getDotnetRuntime.__list;
}
list.registerRuntime(exportedAPI);
configure_emscripten_startup(module, exportedAPI);
if (ENVIRONMENT_IS_WORKER) {
// HACK: Emscripten's dotnet.worker.js expects the exports of dotnet.js module to be Module object
// until we have our own fix for dotnet.worker.js file
return exportedAPI.Module;
}
return exportedAPI;
}
const __initializeImportsAndExports = initializeImportsAndExports; // don't want to export the type
// the methods would be visible to EMCC linker
// --- keep in sync with dotnet.cjs.lib.js ---
const mono_wasm_threads_exports = !MonoWasmThreads ? undefined : {
// mono-threads-wasm.c
mono_wasm_pthread_on_pthread_attached,
// diagnostics_server.c
mono_wasm_diagnostic_server_on_server_thread_created,
mono_wasm_diagnostic_server_on_runtime_server_init,
mono_wasm_diagnostic_server_stream_signal_work_available,
};
// the methods would be visible to EMCC linker
// --- keep in sync with dotnet.cjs.lib.js ---
const __linker_exports = {
// mini-wasm.c
mono_set_timeout,
// mini-wasm-debugger.c
mono_wasm_asm_loaded,
mono_wasm_fire_debugger_agent_message,
mono_wasm_debugger_log,
mono_wasm_add_dbg_command_received,
// mono-threads-wasm.c
schedule_background_exec,
// also keep in sync with driver.c
mono_wasm_invoke_js_blazor,
mono_wasm_trace_logger,
mono_wasm_set_entrypoint_breakpoint,
mono_wasm_event_pipe_early_startup_callback,
// also keep in sync with corebindings.c
mono_wasm_invoke_js_with_args_ref,
mono_wasm_get_object_property_ref,
mono_wasm_set_object_property_ref,
mono_wasm_get_by_index_ref,
mono_wasm_set_by_index_ref,
mono_wasm_get_global_object_ref,
mono_wasm_create_cs_owned_object_ref,
mono_wasm_release_cs_owned_object,
mono_wasm_typed_array_to_array_ref,
mono_wasm_typed_array_copy_to_ref,
mono_wasm_typed_array_from_ref,
mono_wasm_typed_array_copy_from_ref,
mono_wasm_bind_js_function,
mono_wasm_invoke_bound_function,
mono_wasm_bind_cs_function,
mono_wasm_marshal_promise,
// also keep in sync with pal_icushim_static.c
mono_wasm_load_icu_data,
mono_wasm_get_icudt_name,
// pal_crypto_webworker.c
dotnet_browser_can_use_subtle_crypto_impl,
dotnet_browser_simple_digest_hash,
dotnet_browser_sign,
dotnet_browser_encrypt_decrypt,
dotnet_browser_derive_bits,
// threading exports, if threading is enabled
...mono_wasm_threads_exports,
};
const INTERNAL = {
// startup
BINDING_ASM: "[System.Runtime.InteropServices.JavaScript]System.Runtime.InteropServices.JavaScript.JavaScriptExports",
// tests
call_static_method,
mono_wasm_exit: wrapped_c_functions.mono_wasm_exit,
mono_wasm_enable_on_demand_gc: wrapped_c_functions.mono_wasm_enable_on_demand_gc,
mono_profiler_init_aot: wrapped_c_functions.mono_profiler_init_aot,
mono_wasm_set_runtime_options,
mono_wasm_exec_regression: wrapped_c_functions.mono_wasm_exec_regression,
mono_method_resolve,
mono_bind_static_method,
mono_intern_string,
// with mono_wasm_debugger_log and mono_wasm_trace_logger
logging: undefined,
//
mono_wasm_symbolicate_string,
mono_wasm_stringify_as_error_with_stack,
// used in debugger DevToolsHelper.cs
mono_wasm_get_loaded_files,
mono_wasm_send_dbg_command_with_parms,
mono_wasm_send_dbg_command,
mono_wasm_get_dbg_command_info,
mono_wasm_get_details,
mono_wasm_release_object,
mono_wasm_call_function_on,
mono_wasm_debugger_resume,
mono_wasm_detach_debugger,
mono_wasm_raise_debug_event,
mono_wasm_change_debugger_log_level,
mono_wasm_debugger_attached,
mono_wasm_runtime_is_ready: runtimeHelpers.mono_wasm_runtime_is_ready,
// interop
get_property,
set_property,
has_property,
get_typeof_property,
get_global_this,
get_dotnet_instance,
dynamic_import,
// BrowserWebSocket
mono_wasm_cancel_promise,
ws_wasm_create,
ws_wasm_open,
ws_wasm_send,
ws_wasm_receive,
ws_wasm_close,
ws_wasm_abort,
// BrowserHttpHandler
http_wasm_supports_streaming_response,
http_wasm_create_abort_controler,
http_wasm_abort_request,
http_wasm_abort_response,
http_wasm_fetch,
http_wasm_fetch_bytes,
http_wasm_get_response_header_names,
http_wasm_get_response_header_values,
http_wasm_get_response_bytes,
http_wasm_get_response_length,
http_wasm_get_streamed_response_bytes,
};
class RuntimeList {
constructor() {
this.list = {};
}
registerRuntime(api) {
api.RuntimeId = Object.keys(this.list).length;
this.list[api.RuntimeId] = create_weak_ref(api);
return api.RuntimeId;
}
getRuntime(runtimeId) {
const wr = this.list[runtimeId];
return wr ? wr.deref() : undefined;
}
}
function get_dotnet_instance() {
return exportedAPI;
}
exports.__initializeImportsAndExports = __initializeImportsAndExports;
exports.__linker_exports = __linker_exports;
exports.get_dotnet_instance = get_dotnet_instance;
Object.defineProperty(exports, '__esModule', { value: true });
return exports;
})({});
var createDotnetRuntime = (() => {
var _scriptDir = import.meta.url;
return (
function(createDotnetRuntime) {
createDotnetRuntime = createDotnetRuntime || {};
// Support for growable heap + pthreads, where the buffer may change, so JS views
// must be updated.
function GROWABLE_HEAP_I8() {
if (wasmMemory.buffer != buffer) {
updateGlobalBufferAndViews(wasmMemory.buffer);
}
return HEAP8;
}
function GROWABLE_HEAP_U8() {
if (wasmMemory.buffer != buffer) {
updateGlobalBufferAndViews(wasmMemory.buffer);
}
return HEAPU8;
}
function GROWABLE_HEAP_I16() {
if (wasmMemory.buffer != buffer) {
updateGlobalBufferAndViews(wasmMemory.buffer);
}
return HEAP16;
}
function GROWABLE_HEAP_U16() {
if (wasmMemory.buffer != buffer) {
updateGlobalBufferAndViews(wasmMemory.buffer);
}
return HEAPU16;
}
function GROWABLE_HEAP_I32() {
if (wasmMemory.buffer != buffer) {
updateGlobalBufferAndViews(wasmMemory.buffer);
}
return HEAP32;
}
function GROWABLE_HEAP_U32() {
if (wasmMemory.buffer != buffer) {
updateGlobalBufferAndViews(wasmMemory.buffer);
}
return HEAPU32;
}
function GROWABLE_HEAP_F32() {
if (wasmMemory.buffer != buffer) {
updateGlobalBufferAndViews(wasmMemory.buffer);
}
return HEAPF32;
}
function GROWABLE_HEAP_F64() {
if (wasmMemory.buffer != buffer) {
updateGlobalBufferAndViews(wasmMemory.buffer);
}
return HEAPF64;
}
"use strict";
var Module = typeof createDotnetRuntime != "undefined" ? createDotnetRuntime : {};
var readyPromiseResolve, readyPromiseReject;
Module["ready"] = new Promise(function(resolve, reject) {
readyPromiseResolve = resolve;
readyPromiseReject = reject;
});
const MONO = {}, BINDING = {}, INTERNAL = {}, IMPORTS = {}, EXPORTS = {};
let ENVIRONMENT_IS_GLOBAL = false;
var require = require || undefined;
var __dirname = __dirname || "";
if (typeof createDotnetRuntime === "function") {
Module = {
ready: Module.ready
};
const extension = createDotnetRuntime({
MONO: MONO,
BINDING: BINDING,
INTERNAL: INTERNAL,
IMPORTS: IMPORTS,
EXPORTS: EXPORTS,
Module: Module
});
if (extension.ready) {
throw new Error("MONO_WASM: Module.ready couldn't be redefined.");
}
Object.assign(Module, extension);
createDotnetRuntime = Module;
if (!createDotnetRuntime.locateFile) createDotnetRuntime.locateFile = createDotnetRuntime.__locateFile = path => scriptDirectory + path;
} else if (typeof createDotnetRuntime === "object") {
Module = {
ready: Module.ready,
__undefinedConfig: Object.keys(createDotnetRuntime).length === 1
};
Object.assign(Module, createDotnetRuntime);
createDotnetRuntime = Module;
if (!createDotnetRuntime.locateFile) createDotnetRuntime.locateFile = createDotnetRuntime.__locateFile = path => scriptDirectory + path;
} else {
throw new Error("MONO_WASM: Can't use moduleFactory callback of createDotnetRuntime function.");
}
var moduleOverrides = Object.assign({}, Module);
var arguments_ = [];
var thisProgram = "./this.program";
var quit_ = (status, toThrow) => {
throw toThrow;
};
var ENVIRONMENT_IS_WEB = typeof window == "object";
var ENVIRONMENT_IS_WORKER = typeof importScripts == "function";
var ENVIRONMENT_IS_NODE = typeof process == "object" && typeof process.versions == "object" && typeof process.versions.node == "string";
var ENVIRONMENT_IS_SHELL = !ENVIRONMENT_IS_WEB && !ENVIRONMENT_IS_NODE && !ENVIRONMENT_IS_WORKER;
var ENVIRONMENT_IS_PTHREAD = Module["ENVIRONMENT_IS_PTHREAD"] || false;
var scriptDirectory = "";
function locateFile(path) {
if (Module["locateFile"]) {
return Module["locateFile"](path, scriptDirectory);
}
return scriptDirectory + path;
}
var read_, readAsync, readBinary, setWindowTitle;
function logExceptionOnExit(e) {
if (e instanceof ExitStatus) return;
let toLog = e;
err("exiting due to exception: " + toLog);
}
var fs;
var nodePath;
var requireNodeFS;
if (ENVIRONMENT_IS_NODE) {
if (ENVIRONMENT_IS_WORKER) {
scriptDirectory = require("path").dirname(scriptDirectory) + "/";
} else {
scriptDirectory = __dirname + "/";
}
requireNodeFS = () => {
if (!nodePath) {
fs = require("fs");
nodePath = require("path");
}
};
read_ = function shell_read(filename, binary) {
requireNodeFS();
filename = nodePath["normalize"](filename);
return fs.readFileSync(filename, binary ? undefined : "utf8");
};
readBinary = filename => {
var ret = read_(filename, true);
if (!ret.buffer) {
ret = new Uint8Array(ret);
}
return ret;
};
readAsync = (filename, onload, onerror) => {
requireNodeFS();
filename = nodePath["normalize"](filename);
fs.readFile(filename, function(err, data) {
if (err) onerror(err); else onload(data.buffer);
});
};
if (process["argv"].length > 1) {
thisProgram = process["argv"][1].replace(/\\/g, "/");
}
arguments_ = process["argv"].slice(2);
process["on"]("uncaughtException", function(ex) {
if (!(ex instanceof ExitStatus)) {
throw ex;
}
});
process["on"]("unhandledRejection", function(reason) {
throw reason;
});
quit_ = (status, toThrow) => {
if (keepRuntimeAlive()) {
process["exitCode"] = status;
throw toThrow;
}
logExceptionOnExit(toThrow);
process["exit"](status);
};
Module["inspect"] = function() {
return "[Emscripten Module object]";
};
let nodeWorkerThreads;
try {
nodeWorkerThreads = require("worker_threads");
} catch (e) {
console.error('The "worker_threads" module is not supported in this node.js build - perhaps a newer version is needed?');
throw e;
}
global.Worker = nodeWorkerThreads.Worker;
} else if (ENVIRONMENT_IS_SHELL) {
if (typeof read != "undefined") {
read_ = function shell_read(f) {
return read(f);
};
}
readBinary = function readBinary(f) {
let data;
if (typeof readbuffer == "function") {
return new Uint8Array(readbuffer(f));
}
data = read(f, "binary");
assert(typeof data == "object");
return data;
};
readAsync = function readAsync(f, onload, onerror) {
setTimeout(() => onload(readBinary(f)), 0);
};
if (typeof scriptArgs != "undefined") {
arguments_ = scriptArgs;
} else if (typeof arguments != "undefined") {
arguments_ = arguments;
}
if (typeof quit == "function") {
quit_ = (status, toThrow) => {
logExceptionOnExit(toThrow);
quit(status);
};
}
if (typeof print != "undefined") {
if (typeof console == "undefined") console = {};
console.log = print;
console.warn = console.error = typeof printErr != "undefined" ? printErr : print;
}
} else if (ENVIRONMENT_IS_WEB || ENVIRONMENT_IS_WORKER) {
if (ENVIRONMENT_IS_WORKER) {
scriptDirectory = self.location.href;
} else if (typeof document != "undefined" && document.currentScript) {
scriptDirectory = document.currentScript.src;
}
if (_scriptDir) {
scriptDirectory = _scriptDir;
}
if (scriptDirectory.indexOf("blob:") !== 0) {
scriptDirectory = scriptDirectory.substr(0, scriptDirectory.replace(/[?#].*/, "").lastIndexOf("/") + 1);
} else {
scriptDirectory = "";
}
if (!ENVIRONMENT_IS_NODE) {
read_ = url => {
var xhr = new XMLHttpRequest();
xhr.open("GET", url, false);
xhr.send(null);
return xhr.responseText;
};
if (ENVIRONMENT_IS_WORKER) {
readBinary = url => {
var xhr = new XMLHttpRequest();
xhr.open("GET", url, false);
xhr.responseType = "arraybuffer";
xhr.send(null);
return new Uint8Array(xhr.response);
};
}
readAsync = (url, onload, onerror) => {
var xhr = new XMLHttpRequest();
xhr.open("GET", url, true);
xhr.responseType = "arraybuffer";
xhr.onload = () => {
if (xhr.status == 200 || xhr.status == 0 && xhr.response) {
onload(xhr.response);
return;
}
onerror();
};
xhr.onerror = onerror;
xhr.send(null);
};
}
setWindowTitle = title => document.title = title;
} else {}
if (ENVIRONMENT_IS_NODE) {
if (typeof performance == "undefined") {
global.performance = require("perf_hooks").performance;
}
}
var defaultPrint = console.log.bind(console);
var defaultPrintErr = console.warn.bind(console);
if (ENVIRONMENT_IS_NODE) {
requireNodeFS();
defaultPrint = str => fs.writeSync(1, str + "\n");
defaultPrintErr = str => fs.writeSync(2, str + "\n");
}
var out = Module["print"] || defaultPrint;
var err = Module["printErr"] || defaultPrintErr;
Object.assign(Module, moduleOverrides);
moduleOverrides = null;
if (Module["arguments"]) arguments_ = Module["arguments"];
if (Module["thisProgram"]) thisProgram = Module["thisProgram"];
if (Module["quit"]) quit_ = Module["quit"];
var STACK_ALIGN = 16;
var POINTER_SIZE = 4;
function getNativeTypeSize(type) {
switch (type) {
case "i1":
case "i8":
case "u8":
return 1;
case "i16":
case "u16":
return 2;
case "i32":
case "u32":
return 4;
case "i64":
case "u64":
return 8;
case "float":
return 4;
case "double":
return 8;
default:
{
if (type[type.length - 1] === "*") {
return POINTER_SIZE;
} else if (type[0] === "i") {
const bits = Number(type.substr(1));
assert(bits % 8 === 0, "getNativeTypeSize invalid bits " + bits + ", type " + type);
return bits / 8;
} else {
return 0;
}
}
}
}
function warnOnce(text) {
if (!warnOnce.shown) warnOnce.shown = {};
if (!warnOnce.shown[text]) {
warnOnce.shown[text] = 1;
err(text);
}
}
function uleb128Encode(n) {
if (n < 128) {
return [ n ];
}
return [ n % 128 | 128, n >> 7 ];
}
function convertJsFunctionToWasm(func, sig) {
if (typeof WebAssembly.Function == "function") {
var typeNames = {
"i": "i32",
"j": "i64",
"f": "f32",
"d": "f64",
"p": "i32"
};
var type = {
parameters: [],
results: sig[0] == "v" ? [] : [ typeNames[sig[0]] ]
};
for (var i = 1; i < sig.length; ++i) {
type.parameters.push(typeNames[sig[i]]);
}
return new WebAssembly.Function(type, func);
}
var typeSection = [ 1, 96 ];
var sigRet = sig.slice(0, 1);
var sigParam = sig.slice(1);
var typeCodes = {
"i": 127,
"p": 127,
"j": 126,
"f": 125,
"d": 124
};
typeSection = typeSection.concat(uleb128Encode(sigParam.length));
for (var i = 0; i < sigParam.length; ++i) {
typeSection.push(typeCodes[sigParam[i]]);
}
if (sigRet == "v") {
typeSection.push(0);
} else {
typeSection = typeSection.concat([ 1, typeCodes[sigRet] ]);
}
typeSection = [ 1 ].concat(uleb128Encode(typeSection.length), typeSection);
var bytes = new Uint8Array([ 0, 97, 115, 109, 1, 0, 0, 0 ].concat(typeSection, [ 2, 7, 1, 1, 101, 1, 102, 0, 0, 7, 5, 1, 1, 102, 0, 0 ]));
var module = new WebAssembly.Module(bytes);
var instance = new WebAssembly.Instance(module, {
"e": {
"f": func
}
});
var wrappedFunc = instance.exports["f"];
return wrappedFunc;
}
var freeTableIndexes = [];
var functionsInTableMap;
function getEmptyTableSlot() {
if (freeTableIndexes.length) {
return freeTableIndexes.pop();
}
try {
wasmTable.grow(1);
} catch (err) {
if (!(err instanceof RangeError)) {
throw err;
}
throw "Unable to grow wasm table. Set ALLOW_TABLE_GROWTH.";
}
return wasmTable.length - 1;
}
function updateTableMap(offset, count) {
for (var i = offset; i < offset + count; i++) {
var item = getWasmTableEntry(i);
if (item) {
functionsInTableMap.set(item, i);
}
}
}
function addFunction(func, sig) {
if (!functionsInTableMap) {
functionsInTableMap = new WeakMap();
updateTableMap(0, wasmTable.length);
}
if (functionsInTableMap.has(func)) {
return functionsInTableMap.get(func);
}
var ret = getEmptyTableSlot();
try {
setWasmTableEntry(ret, func);
} catch (err) {
if (!(err instanceof TypeError)) {
throw err;
}
var wrapped = convertJsFunctionToWasm(func, sig);
setWasmTableEntry(ret, wrapped);
}
functionsInTableMap.set(func, ret);
return ret;
}
function removeFunction(index) {
functionsInTableMap.delete(getWasmTableEntry(index));
freeTableIndexes.push(index);
}
var tempRet0 = 0;
var setTempRet0 = value => {
tempRet0 = value;
};
var getTempRet0 = () => tempRet0;
var Atomics_load = Atomics.load;
var Atomics_store = Atomics.store;
var Atomics_compareExchange = Atomics.compareExchange;
var wasmBinary;
if (Module["wasmBinary"]) wasmBinary = Module["wasmBinary"];
var noExitRuntime = Module["noExitRuntime"] || true;
if (typeof WebAssembly != "object") {
abort("no native wasm support detected");
}
var wasmMemory;
var wasmModule;
var ABORT = false;
var EXITSTATUS;
function assert(condition, text) {
if (!condition) {
abort(text);
}
}
function getCFunc(ident) {
var func = Module["_" + ident];
return func;
}
function ccall(ident, returnType, argTypes, args, opts) {
var toC = {
"string": function(str) {
var ret = 0;
if (str !== null && str !== undefined && str !== 0) {
var len = (str.length << 2) + 1;
ret = stackAlloc(len);
stringToUTF8(str, ret, len);
}
return ret;
},
"array": function(arr) {
var ret = stackAlloc(arr.length);
writeArrayToMemory(arr, ret);
return ret;
}
};
function convertReturnValue(ret) {
if (returnType === "string") {
return UTF8ToString(ret);
}
if (returnType === "boolean") return Boolean(ret);
return ret;
}
var func = getCFunc(ident);
var cArgs = [];
var stack = 0;
if (args) {
for (var i = 0; i < args.length; i++) {
var converter = toC[argTypes[i]];
if (converter) {
if (stack === 0) stack = stackSave();
cArgs[i] = converter(args[i]);
} else {
cArgs[i] = args[i];
}
}
}
var ret = func.apply(null, cArgs);
function onDone(ret) {
if (stack !== 0) stackRestore(stack);
return convertReturnValue(ret);
}
ret = onDone(ret);
return ret;
}
function cwrap(ident, returnType, argTypes, opts) {
argTypes = argTypes || [];
var numericArgs = argTypes.every(function(type) {
return type === "number";
});
var numericRet = returnType !== "string";
if (numericRet && numericArgs && !opts) {
return getCFunc(ident);
}
return function() {
return ccall(ident, returnType, argTypes, arguments, opts);
};
}
var ALLOC_NORMAL = 0;
var ALLOC_STACK = 1;
function allocate(slab, allocator) {
var ret;
if (allocator == ALLOC_STACK) {
ret = stackAlloc(slab.length);
} else {
ret = _malloc(slab.length);
}
if (!slab.subarray && !slab.slice) {
slab = new Uint8Array(slab);
}
GROWABLE_HEAP_U8().set(slab, ret);
return ret;
}
var UTF8Decoder = typeof TextDecoder != "undefined" ? new TextDecoder("utf8") : undefined;
function UTF8ArrayToString(heapOrArray, idx, maxBytesToRead) {
var endIdx = idx + maxBytesToRead;
var endPtr = idx;
while (heapOrArray[endPtr] && !(endPtr >= endIdx)) ++endPtr;
if (endPtr - idx > 16 && heapOrArray.buffer && UTF8Decoder) {
return UTF8Decoder.decode(heapOrArray.buffer instanceof SharedArrayBuffer ? heapOrArray.slice(idx, endPtr) : heapOrArray.subarray(idx, endPtr));
} else {
var str = "";
while (idx < endPtr) {
var u0 = heapOrArray[idx++];
if (!(u0 & 128)) {
str += String.fromCharCode(u0);
continue;
}
var u1 = heapOrArray[idx++] & 63;
if ((u0 & 224) == 192) {
str += String.fromCharCode((u0 & 31) << 6 | u1);
continue;
}
var u2 = heapOrArray[idx++] & 63;
if ((u0 & 240) == 224) {
u0 = (u0 & 15) << 12 | u1 << 6 | u2;
} else {
u0 = (u0 & 7) << 18 | u1 << 12 | u2 << 6 | heapOrArray[idx++] & 63;
}
if (u0 < 65536) {
str += String.fromCharCode(u0);
} else {
var ch = u0 - 65536;
str += String.fromCharCode(55296 | ch >> 10, 56320 | ch & 1023);
}
}
}
return str;
}
function UTF8ToString(ptr, maxBytesToRead) {
return ptr ? UTF8ArrayToString(GROWABLE_HEAP_U8(), ptr, maxBytesToRead) : "";
}
function stringToUTF8Array(str, heap, outIdx, maxBytesToWrite) {
if (!(maxBytesToWrite > 0)) return 0;
var startIdx = outIdx;
var endIdx = outIdx + maxBytesToWrite - 1;
for (var i = 0; i < str.length; ++i) {
var u = str.charCodeAt(i);
if (u >= 55296 && u <= 57343) {
var u1 = str.charCodeAt(++i);
u = 65536 + ((u & 1023) << 10) | u1 & 1023;
}
if (u <= 127) {
if (outIdx >= endIdx) break;
heap[outIdx++] = u;
} else if (u <= 2047) {
if (outIdx + 1 >= endIdx) break;
heap[outIdx++] = 192 | u >> 6;
heap[outIdx++] = 128 | u & 63;
} else if (u <= 65535) {
if (outIdx + 2 >= endIdx) break;
heap[outIdx++] = 224 | u >> 12;
heap[outIdx++] = 128 | u >> 6 & 63;
heap[outIdx++] = 128 | u & 63;
} else {
if (outIdx + 3 >= endIdx) break;
heap[outIdx++] = 240 | u >> 18;
heap[outIdx++] = 128 | u >> 12 & 63;
heap[outIdx++] = 128 | u >> 6 & 63;
heap[outIdx++] = 128 | u & 63;
}
}
heap[outIdx] = 0;
return outIdx - startIdx;
}
function stringToUTF8(str, outPtr, maxBytesToWrite) {
return stringToUTF8Array(str, GROWABLE_HEAP_U8(), outPtr, maxBytesToWrite);
}
function lengthBytesUTF8(str) {
var len = 0;
for (var i = 0; i < str.length; ++i) {
var u = str.charCodeAt(i);
if (u >= 55296 && u <= 57343) u = 65536 + ((u & 1023) << 10) | str.charCodeAt(++i) & 1023;
if (u <= 127) ++len; else if (u <= 2047) len += 2; else if (u <= 65535) len += 3; else len += 4;
}
return len;
}
function AsciiToString(ptr) {
var str = "";
while (1) {
var ch = GROWABLE_HEAP_U8()[ptr++ >> 0];
if (!ch) return str;
str += String.fromCharCode(ch);
}
}
function stringToAscii(str, outPtr) {
return writeAsciiToMemory(str, outPtr, false);
}
var UTF16Decoder = typeof TextDecoder != "undefined" ? new TextDecoder("utf-16le") : undefined;
function UTF16ToString(ptr, maxBytesToRead) {
var endPtr = ptr;
var idx = endPtr >> 1;
var maxIdx = idx + maxBytesToRead / 2;
while (!(idx >= maxIdx) && GROWABLE_HEAP_U16()[idx]) ++idx;
endPtr = idx << 1;
if (endPtr - ptr > 32 && UTF16Decoder) {
return UTF16Decoder.decode(GROWABLE_HEAP_U8().slice(ptr, endPtr));
} else {
var str = "";
for (var i = 0; !(i >= maxBytesToRead / 2); ++i) {
var codeUnit = GROWABLE_HEAP_I16()[ptr + i * 2 >> 1];
if (codeUnit == 0) break;
str += String.fromCharCode(codeUnit);
}
return str;
}
}
function stringToUTF16(str, outPtr, maxBytesToWrite) {
if (maxBytesToWrite === undefined) {
maxBytesToWrite = 2147483647;
}
if (maxBytesToWrite < 2) return 0;
maxBytesToWrite -= 2;
var startPtr = outPtr;
var numCharsToWrite = maxBytesToWrite < str.length * 2 ? maxBytesToWrite / 2 : str.length;
for (var i = 0; i < numCharsToWrite; ++i) {
var codeUnit = str.charCodeAt(i);
GROWABLE_HEAP_I16()[outPtr >> 1] = codeUnit;
outPtr += 2;
}
GROWABLE_HEAP_I16()[outPtr >> 1] = 0;
return outPtr - startPtr;
}
function lengthBytesUTF16(str) {
return str.length * 2;
}
function UTF32ToString(ptr, maxBytesToRead) {
var i = 0;
var str = "";
while (!(i >= maxBytesToRead / 4)) {
var utf32 = GROWABLE_HEAP_I32()[ptr + i * 4 >> 2];
if (utf32 == 0) break;
++i;
if (utf32 >= 65536) {
var ch = utf32 - 65536;
str += String.fromCharCode(55296 | ch >> 10, 56320 | ch & 1023);
} else {
str += String.fromCharCode(utf32);
}
}
return str;
}
function stringToUTF32(str, outPtr, maxBytesToWrite) {
if (maxBytesToWrite === undefined) {
maxBytesToWrite = 2147483647;
}
if (maxBytesToWrite < 4) return 0;
var startPtr = outPtr;
var endPtr = startPtr + maxBytesToWrite - 4;
for (var i = 0; i < str.length; ++i) {
var codeUnit = str.charCodeAt(i);
if (codeUnit >= 55296 && codeUnit <= 57343) {
var trailSurrogate = str.charCodeAt(++i);
codeUnit = 65536 + ((codeUnit & 1023) << 10) | trailSurrogate & 1023;
}
GROWABLE_HEAP_I32()[outPtr >> 2] = codeUnit;
outPtr += 4;
if (outPtr + 4 > endPtr) break;
}
GROWABLE_HEAP_I32()[outPtr >> 2] = 0;
return outPtr - startPtr;
}
function lengthBytesUTF32(str) {
var len = 0;
for (var i = 0; i < str.length; ++i) {
var codeUnit = str.charCodeAt(i);
if (codeUnit >= 55296 && codeUnit <= 57343) ++i;
len += 4;
}
return len;
}
function allocateUTF8(str) {
var size = lengthBytesUTF8(str) + 1;
var ret = _malloc(size);
if (ret) stringToUTF8Array(str, GROWABLE_HEAP_I8(), ret, size);
return ret;
}
function allocateUTF8OnStack(str) {
var size = lengthBytesUTF8(str) + 1;
var ret = stackAlloc(size);
stringToUTF8Array(str, GROWABLE_HEAP_I8(), ret, size);
return ret;
}
function writeStringToMemory(string, buffer, dontAddNull) {
warnOnce("writeStringToMemory is deprecated and should not be called! Use stringToUTF8() instead!");
var lastChar, end;
if (dontAddNull) {
end = buffer + lengthBytesUTF8(string);
lastChar = GROWABLE_HEAP_I8()[end];
}
stringToUTF8(string, buffer, Infinity);
if (dontAddNull) GROWABLE_HEAP_I8()[end] = lastChar;
}
function writeArrayToMemory(array, buffer) {
GROWABLE_HEAP_I8().set(array, buffer);
}
function writeAsciiToMemory(str, buffer, dontAddNull) {
for (var i = 0; i < str.length; ++i) {
GROWABLE_HEAP_I8()[buffer++ >> 0] = str.charCodeAt(i);
}
if (!dontAddNull) GROWABLE_HEAP_I8()[buffer >> 0] = 0;
}
var HEAP, buffer, HEAP8, HEAPU8, HEAP16, HEAPU16, HEAP32, HEAPU32, HEAPF32, HEAPF64;
if (ENVIRONMENT_IS_PTHREAD) {
buffer = Module["buffer"];
}
function updateGlobalBufferAndViews(buf) {
buffer = buf;
Module["HEAP8"] = HEAP8 = new Int8Array(buf);
Module["HEAP16"] = HEAP16 = new Int16Array(buf);
Module["HEAP32"] = HEAP32 = new Int32Array(buf);
Module["HEAPU8"] = HEAPU8 = new Uint8Array(buf);
Module["HEAPU16"] = HEAPU16 = new Uint16Array(buf);
Module["HEAPU32"] = HEAPU32 = new Uint32Array(buf);
Module["HEAPF32"] = HEAPF32 = new Float32Array(buf);
Module["HEAPF64"] = HEAPF64 = new Float64Array(buf);
}
var TOTAL_STACK = 5242880;
var INITIAL_MEMORY = Module["INITIAL_MEMORY"] || 16777216;
if (ENVIRONMENT_IS_PTHREAD) {
wasmMemory = Module["wasmMemory"];
buffer = Module["buffer"];
} else {
if (Module["wasmMemory"]) {
wasmMemory = Module["wasmMemory"];
} else {
wasmMemory = new WebAssembly.Memory({
"initial": INITIAL_MEMORY / 65536,
"maximum": 2147483648 / 65536,
"shared": true
});
if (!(wasmMemory.buffer instanceof SharedArrayBuffer)) {
err("requested a shared WebAssembly.Memory but the returned buffer is not a SharedArrayBuffer, indicating that while the browser has SharedArrayBuffer it does not have WebAssembly threads support - you may need to set a flag");
if (ENVIRONMENT_IS_NODE) {
console.log("(on node you may need: --experimental-wasm-threads --experimental-wasm-bulk-memory and also use a recent version)");
}
throw Error("bad memory");
}
}
}
if (wasmMemory) {
buffer = wasmMemory.buffer;
}
INITIAL_MEMORY = buffer.byteLength;
updateGlobalBufferAndViews(buffer);
var wasmTable;
var __ATPRERUN__ = [];
var __ATINIT__ = [];
var __ATEXIT__ = [];
var __ATPOSTRUN__ = [];
var runtimeInitialized = false;
function keepRuntimeAlive() {
return noExitRuntime;
}
function preRun() {
if (Module["preRun"]) {
if (typeof Module["preRun"] == "function") Module["preRun"] = [ Module["preRun"] ];
while (Module["preRun"].length) {
addOnPreRun(Module["preRun"].shift());
}
}
callRuntimeCallbacks(__ATPRERUN__);
}
function initRuntime() {
runtimeInitialized = true;
if (ENVIRONMENT_IS_PTHREAD) return;
if (!Module["noFSInit"] && !FS.init.initialized) FS.init();
FS.ignorePermissions = false;
TTY.init();
SOCKFS.root = FS.mount(SOCKFS, {}, null);
callRuntimeCallbacks(__ATINIT__);
}
function postRun() {
if (ENVIRONMENT_IS_PTHREAD) return;
if (Module["postRun"]) {
if (typeof Module["postRun"] == "function") Module["postRun"] = [ Module["postRun"] ];
while (Module["postRun"].length) {
addOnPostRun(Module["postRun"].shift());
}
}
callRuntimeCallbacks(__ATPOSTRUN__);
}
function addOnPreRun(cb) {
__ATPRERUN__.unshift(cb);
}
function addOnInit(cb) {
__ATINIT__.unshift(cb);
}
function addOnExit(cb) {}
function addOnPostRun(cb) {
__ATPOSTRUN__.unshift(cb);
}
var runDependencies = 0;
var runDependencyWatcher = null;
var dependenciesFulfilled = null;
function getUniqueRunDependency(id) {
return id;
}
function addRunDependency(id) {
runDependencies++;
if (Module["monitorRunDependencies"]) {
Module["monitorRunDependencies"](runDependencies);
}
}
function removeRunDependency(id) {
runDependencies--;
if (Module["monitorRunDependencies"]) {
Module["monitorRunDependencies"](runDependencies);
}
if (runDependencies == 0) {
if (runDependencyWatcher !== null) {
clearInterval(runDependencyWatcher);
runDependencyWatcher = null;
}
if (dependenciesFulfilled) {
var callback = dependenciesFulfilled;
dependenciesFulfilled = null;
callback();
}
}
}
function abort(what) {
if (ENVIRONMENT_IS_PTHREAD) {
postMessage({
"cmd": "onAbort",
"arg": what
});
} else {
if (Module["onAbort"]) {
Module["onAbort"](what);
}
}
what = "Aborted(" + what + ")";
err(what);
ABORT = true;
EXITSTATUS = 1;
what += ". Build with -sASSERTIONS for more info.";
var e = new WebAssembly.RuntimeError(what);
readyPromiseReject(e);
throw e;
}
var dataURIPrefix = "data:application/octet-stream;base64,";
function isDataURI(filename) {
return filename.startsWith(dataURIPrefix);
}
function isFileURI(filename) {
return filename.startsWith("file://");
}
var wasmBinaryFile;
if (Module["locateFile"]) {
wasmBinaryFile = "dotnet.wasm";
if (!isDataURI(wasmBinaryFile)) {
wasmBinaryFile = locateFile(wasmBinaryFile);
}
} else {
wasmBinaryFile = new URL("dotnet.wasm", import.meta.url).toString();
}
function getBinary(file) {
try {
if (file == wasmBinaryFile && wasmBinary) {
return new Uint8Array(wasmBinary);
}
if (readBinary) {
return readBinary(file);
} else {
throw "both async and sync fetching of the wasm failed";
}
} catch (err) {
abort(err);
}
}
function getBinaryPromise() {
if (!wasmBinary && (ENVIRONMENT_IS_WEB || ENVIRONMENT_IS_WORKER)) {
if (typeof fetch == "function" && !isFileURI(wasmBinaryFile)) {
return fetch(wasmBinaryFile, {
credentials: "same-origin"
}).then(function(response) {
if (!response["ok"]) {
throw "failed to load wasm binary file at '" + wasmBinaryFile + "'";
}
return response["arrayBuffer"]();
}).catch(function() {
return getBinary(wasmBinaryFile);
});
} else {
if (readAsync) {
return new Promise(function(resolve, reject) {
readAsync(wasmBinaryFile, function(response) {
resolve(new Uint8Array(response));
}, reject);
});
}
}
}
return Promise.resolve().then(function() {
return getBinary(wasmBinaryFile);
});
}
function createWasm() {
var info = {
"env": asmLibraryArg,
"wasi_snapshot_preview1": asmLibraryArg
};
function receiveInstance(instance, module) {
var exports = instance.exports;
Module["asm"] = exports;
registerTLSInit(Module["asm"]["_emscripten_tls_init"]);
wasmTable = Module["asm"]["__indirect_function_table"];
addOnInit(Module["asm"]["__wasm_call_ctors"]);
wasmModule = module;
if (!ENVIRONMENT_IS_PTHREAD) {
var numWorkersToLoad = PThread.unusedWorkers.length;
PThread.unusedWorkers.forEach(function(w) {
PThread.loadWasmModuleToWorker(w, function() {
if (!--numWorkersToLoad) removeRunDependency("wasm-instantiate");
});
});
}
}
if (!ENVIRONMENT_IS_PTHREAD) {
addRunDependency("wasm-instantiate");
}
function receiveInstantiationResult(result) {
receiveInstance(result["instance"], result["module"]);
}
function instantiateArrayBuffer(receiver) {
return getBinaryPromise().then(function(binary) {
return WebAssembly.instantiate(binary, info);
}).then(function(instance) {
return instance;
}).then(receiver, function(reason) {
err("failed to asynchronously prepare wasm: " + reason);
abort(reason);
});
}
function instantiateAsync() {
if (!wasmBinary && typeof WebAssembly.instantiateStreaming == "function" && !isDataURI(wasmBinaryFile) && !isFileURI(wasmBinaryFile) && typeof fetch == "function") {
return fetch(wasmBinaryFile, {
credentials: "same-origin"
}).then(function(response) {
var result = WebAssembly.instantiateStreaming(response, info);
return result.then(receiveInstantiationResult, function(reason) {
err("wasm streaming compile failed: " + reason);
err("falling back to ArrayBuffer instantiation");
return instantiateArrayBuffer(receiveInstantiationResult);
});
});
} else {
return instantiateArrayBuffer(receiveInstantiationResult);
}
}
if (Module["instantiateWasm"]) {
try {
var exports = Module["instantiateWasm"](info, receiveInstance);
return exports;
} catch (e) {
err("Module.instantiateWasm callback failed with error: " + e);
return false;
}
}
instantiateAsync().catch(readyPromiseReject);
return {};
}
var tempDouble;
var tempI64;
var ASM_CONSTS = {};
function killThread(pthread_ptr) {
var pthread = PThread.pthreads[pthread_ptr];
delete PThread.pthreads[pthread_ptr];
pthread.worker.terminate();
__emscripten_thread_free_data(pthread_ptr);
PThread.runningWorkers.splice(PThread.runningWorkers.indexOf(pthread.worker), 1);
pthread.worker.pthread = undefined;
}
function cancelThread(pthread_ptr) {
var pthread = PThread.pthreads[pthread_ptr];
pthread.worker.postMessage({
"cmd": "cancel"
});
}
function cleanupThread(pthread_ptr) {
var pthread = PThread.pthreads[pthread_ptr];
assert(pthread);
var worker = pthread.worker;
PThread.returnWorkerToPool(worker);
}
function zeroMemory(address, size) {
GROWABLE_HEAP_U8().fill(0, address, address + size);
}
function ptrToString(ptr) {
return "0x" + ptr.toString(16).padStart(8, "0");
}
function spawnThread(threadParams) {
var worker = PThread.getNewWorker();
if (!worker) {
return 6;
}
PThread.runningWorkers.push(worker);
var pthread = PThread.pthreads[threadParams.pthread_ptr] = {
worker: worker,
threadInfoStruct: threadParams.pthread_ptr
};
worker.pthread = pthread;
var msg = {
"cmd": "run",
"start_routine": threadParams.startRoutine,
"arg": threadParams.arg,
"threadInfoStruct": threadParams.pthread_ptr
};
worker.runPthread = () => {
msg.time = performance.now();
worker.postMessage(msg, threadParams.transferList);
};
if (worker.loaded) {
worker.runPthread();
delete worker.runPthread;
}
return 0;
}
function _exit(status) {
exit(status);
}
function handleException(e) {
if (e instanceof ExitStatus || e == "unwind") {
return EXITSTATUS;
}
quit_(1, e);
}
var PThread = {
unusedWorkers: [],
runningWorkers: [],
tlsInitFunctions: [],
init: function() {
if (ENVIRONMENT_IS_PTHREAD) {
PThread.initWorker();
} else {
PThread.initMainThread();
}
},
initMainThread: function() {
var pthreadPoolSize = 4;
for (var i = 0; i < pthreadPoolSize; ++i) {
PThread.allocateUnusedWorker();
}
},
initWorker: function() {
noExitRuntime = false;
},
pthreads: {},
setExitStatus: function(status) {
EXITSTATUS = status;
},
terminateAllThreads: function() {
for (var t in PThread.pthreads) {
var pthread = PThread.pthreads[t];
if (pthread && pthread.worker) {
PThread.returnWorkerToPool(pthread.worker);
}
}
for (var i = 0; i < PThread.unusedWorkers.length; ++i) {
var worker = PThread.unusedWorkers[i];
worker.terminate();
}
PThread.unusedWorkers = [];
},
returnWorkerToPool: function(worker) {
var pthread_ptr = worker.pthread.threadInfoStruct;
delete PThread.pthreads[pthread_ptr];
PThread.unusedWorkers.push(worker);
PThread.runningWorkers.splice(PThread.runningWorkers.indexOf(worker), 1);
worker.pthread = undefined;
__emscripten_thread_free_data(pthread_ptr);
},
receiveObjectTransfer: function(data) {},
threadInitTLS: function() {
for (var i in PThread.tlsInitFunctions) {
if (PThread.tlsInitFunctions.hasOwnProperty(i)) PThread.tlsInitFunctions[i]();
}
},
loadWasmModuleToWorker: function(worker, onFinishedLoading) {
worker.onmessage = e => {
var d = e["data"];
var cmd = d["cmd"];
if (worker.pthread) PThread.currentProxiedOperationCallerThread = worker.pthread.threadInfoStruct;
if (d["targetThread"] && d["targetThread"] != _pthread_self()) {
var thread = PThread.pthreads[d.targetThread];
if (thread) {
thread.worker.postMessage(d, d["transferList"]);
} else {
err('Internal error! Worker sent a message "' + cmd + '" to target pthread ' + d["targetThread"] + ", but that thread no longer exists!");
}
PThread.currentProxiedOperationCallerThread = undefined;
return;
}
if (cmd === "processProxyingQueue") {
executeNotifiedProxyingQueue(d["queue"]);
} else if (cmd === "spawnThread") {
spawnThread(d);
} else if (cmd === "cleanupThread") {
cleanupThread(d["thread"]);
} else if (cmd === "killThread") {
killThread(d["thread"]);
} else if (cmd === "cancelThread") {
cancelThread(d["thread"]);
} else if (cmd === "loaded") {
worker.loaded = true;
if (onFinishedLoading) onFinishedLoading(worker);
if (worker.runPthread) {
worker.runPthread();
delete worker.runPthread;
}
} else if (cmd === "print") {
out("Thread " + d["threadId"] + ": " + d["text"]);
} else if (cmd === "printErr") {
err("Thread " + d["threadId"] + ": " + d["text"]);
} else if (cmd === "alert") {
alert("Thread " + d["threadId"] + ": " + d["text"]);
} else if (d.target === "setimmediate") {
worker.postMessage(d);
} else if (cmd === "onAbort") {
if (Module["onAbort"]) {
Module["onAbort"](d["arg"]);
}
} else if (cmd) {
err("worker sent an unknown command " + cmd);
}
PThread.currentProxiedOperationCallerThread = undefined;
};
worker.onerror = e => {
var message = "worker sent an error!";
err(message + " " + e.filename + ":" + e.lineno + ": " + e.message);
throw e;
};
if (ENVIRONMENT_IS_NODE) {
worker.on("message", function(data) {
worker.onmessage({
data: data
});
});
worker.on("error", function(e) {
worker.onerror(e);
});
worker.on("detachedExit", function() {});
}
worker.postMessage({
"cmd": "load",
"urlOrBlob": Module["mainScriptUrlOrBlob"],
"wasmMemory": wasmMemory,
"wasmModule": wasmModule
});
},
allocateUnusedWorker: function() {
if (!Module["locateFile"]) {
PThread.unusedWorkers.push(new Worker(new URL("dotnet.worker.js", import.meta.url)));
return;
}
var pthreadMainJs = locateFile("dotnet.worker.js");
PThread.unusedWorkers.push(new Worker(pthreadMainJs));
},
getNewWorker: function() {
if (PThread.unusedWorkers.length == 0) {
return;
PThread.allocateUnusedWorker();
PThread.loadWasmModuleToWorker(PThread.unusedWorkers[0]);
}
return PThread.unusedWorkers.pop();
}
};
Module["PThread"] = PThread;
function callRuntimeCallbacks(callbacks) {
while (callbacks.length > 0) {
var callback = callbacks.shift();
if (typeof callback == "function") {
callback(Module);
continue;
}
var func = callback.func;
if (typeof func == "number") {
if (callback.arg === undefined) {
getWasmTableEntry(func)();
} else {
getWasmTableEntry(func)(callback.arg);
}
} else {
func(callback.arg === undefined ? null : callback.arg);
}
}
}
function withStackSave(f) {
var stack = stackSave();
var ret = f();
stackRestore(stack);
return ret;
}
function demangle(func) {
return func;
}
function demangleAll(text) {
var regex = /\b_Z[\w\d_]+/g;
return text.replace(regex, function(x) {
var y = demangle(x);
return x === y ? x : y + " [" + x + "]";
});
}
function establishStackSpace() {
var pthread_ptr = _pthread_self();
var stackTop = GROWABLE_HEAP_I32()[pthread_ptr + 44 >> 2];
var stackSize = GROWABLE_HEAP_I32()[pthread_ptr + 48 >> 2];
var stackMax = stackTop - stackSize;
_emscripten_stack_set_limits(stackTop, stackMax);
stackRestore(stackTop);
}
Module["establishStackSpace"] = establishStackSpace;
function exitOnMainThread(returnCode) {
if (ENVIRONMENT_IS_PTHREAD) return _emscripten_proxy_to_main_thread_js(1, 0, returnCode);
try {
_exit(returnCode);
} catch (e) {
handleException(e);
}
}
function getValue(ptr, type = "i8") {
if (type.endsWith("*")) type = "i32";
switch (type) {
case "i1":
return GROWABLE_HEAP_I8()[ptr >> 0];
case "i8":
return GROWABLE_HEAP_I8()[ptr >> 0];
case "i16":
return GROWABLE_HEAP_I16()[ptr >> 1];
case "i32":
return GROWABLE_HEAP_I32()[ptr >> 2];
case "i64":
return GROWABLE_HEAP_I32()[ptr >> 2];
case "float":
return GROWABLE_HEAP_F32()[ptr >> 2];
case "double":
return Number(GROWABLE_HEAP_F64()[ptr >> 3]);
default:
abort("invalid type for getValue: " + type);
}
return null;
}
function getWasmTableEntry(funcPtr) {
return wasmTable.get(funcPtr);
}
function invokeEntryPoint(ptr, arg) {
return getWasmTableEntry(ptr)(arg);
}
Module["invokeEntryPoint"] = invokeEntryPoint;
function jsStackTrace() {
var error = new Error();
if (!error.stack) {
try {
throw new Error();
} catch (e) {
error = e;
}
if (!error.stack) {
return "(no stack trace available)";
}
}
return error.stack.toString();
}
function registerTLSInit(tlsInitFunc) {
PThread.tlsInitFunctions.push(tlsInitFunc);
}
function setValue(ptr, value, type = "i8") {
if (type.endsWith("*")) type = "i32";
switch (type) {
case "i1":
GROWABLE_HEAP_I8()[ptr >> 0] = value;
break;
case "i8":
GROWABLE_HEAP_I8()[ptr >> 0] = value;
break;
case "i16":
GROWABLE_HEAP_I16()[ptr >> 1] = value;
break;
case "i32":
GROWABLE_HEAP_I32()[ptr >> 2] = value;
break;
case "i64":
tempI64 = [ value >>> 0, (tempDouble = value, +Math.abs(tempDouble) >= 1 ? tempDouble > 0 ? (Math.min(+Math.floor(tempDouble / 4294967296), 4294967295) | 0) >>> 0 : ~~+Math.ceil((tempDouble - +(~~tempDouble >>> 0)) / 4294967296) >>> 0 : 0) ],
GROWABLE_HEAP_I32()[ptr >> 2] = tempI64[0], GROWABLE_HEAP_I32()[ptr + 4 >> 2] = tempI64[1];
break;
case "float":
GROWABLE_HEAP_F32()[ptr >> 2] = value;
break;
case "double":
GROWABLE_HEAP_F64()[ptr >> 3] = value;
break;
default:
abort("invalid type for setValue: " + type);
}
}
function setWasmTableEntry(idx, func) {
wasmTable.set(idx, func);
}
function stackTrace() {
var js = jsStackTrace();
if (Module["extraStackTrace"]) js += "\n" + Module["extraStackTrace"]();
return demangleAll(js);
}
function ___assert_fail(condition, filename, line, func) {
abort("Assertion failed: " + UTF8ToString(condition) + ", at: " + [ filename ? UTF8ToString(filename) : "unknown filename", line, func ? UTF8ToString(func) : "unknown function" ]);
}
function ___cxa_allocate_exception(size) {
return _malloc(size + 24) + 24;
}
var exceptionCaught = [];
function exception_addRef(info) {
info.add_ref();
}
var uncaughtExceptionCount = 0;
function ___cxa_begin_catch(ptr) {
var info = new ExceptionInfo(ptr);
if (!info.get_caught()) {
info.set_caught(true);
uncaughtExceptionCount--;
}
info.set_rethrown(false);
exceptionCaught.push(info);
exception_addRef(info);
return info.get_exception_ptr();
}
var exceptionLast = 0;
function ExceptionInfo(excPtr) {
this.excPtr = excPtr;
this.ptr = excPtr - 24;
this.set_type = function(type) {
GROWABLE_HEAP_U32()[this.ptr + 4 >> 2] = type;
};
this.get_type = function() {
return GROWABLE_HEAP_U32()[this.ptr + 4 >> 2];
};
this.set_destructor = function(destructor) {
GROWABLE_HEAP_U32()[this.ptr + 8 >> 2] = destructor;
};
this.get_destructor = function() {
return GROWABLE_HEAP_U32()[this.ptr + 8 >> 2];
};
this.set_refcount = function(refcount) {
GROWABLE_HEAP_I32()[this.ptr >> 2] = refcount;
};
this.set_caught = function(caught) {
caught = caught ? 1 : 0;
GROWABLE_HEAP_I8()[this.ptr + 12 >> 0] = caught;
};
this.get_caught = function() {
return GROWABLE_HEAP_I8()[this.ptr + 12 >> 0] != 0;
};
this.set_rethrown = function(rethrown) {
rethrown = rethrown ? 1 : 0;
GROWABLE_HEAP_I8()[this.ptr + 13 >> 0] = rethrown;
};
this.get_rethrown = function() {
return GROWABLE_HEAP_I8()[this.ptr + 13 >> 0] != 0;
};
this.init = function(type, destructor) {
this.set_adjusted_ptr(0);
this.set_type(type);
this.set_destructor(destructor);
this.set_refcount(0);
this.set_caught(false);
this.set_rethrown(false);
};
this.add_ref = function() {
Atomics.add(GROWABLE_HEAP_I32(), this.ptr + 0 >> 2, 1);
};
this.release_ref = function() {
var prev = Atomics.sub(GROWABLE_HEAP_I32(), this.ptr + 0 >> 2, 1);
return prev === 1;
};
this.set_adjusted_ptr = function(adjustedPtr) {
GROWABLE_HEAP_U32()[this.ptr + 16 >> 2] = adjustedPtr;
};
this.get_adjusted_ptr = function() {
return GROWABLE_HEAP_U32()[this.ptr + 16 >> 2];
};
this.get_exception_ptr = function() {
var isPointer = ___cxa_is_pointer_type(this.get_type());
if (isPointer) {
return GROWABLE_HEAP_U32()[this.excPtr >> 2];
}
var adjusted = this.get_adjusted_ptr();
if (adjusted !== 0) return adjusted;
return this.excPtr;
};
}
function ___cxa_free_exception(ptr) {
return _free(new ExceptionInfo(ptr).ptr);
}
function exception_decRef(info) {
if (info.release_ref() && !info.get_rethrown()) {
var destructor = info.get_destructor();
if (destructor) {
getWasmTableEntry(destructor)(info.excPtr);
}
___cxa_free_exception(info.excPtr);
}
}
function ___cxa_end_catch() {
_setThrew(0);
var info = exceptionCaught.pop();
exception_decRef(info);
exceptionLast = 0;
}
function ___resumeException(ptr) {
if (!exceptionLast) {
exceptionLast = ptr;
}
throw ptr;
}
function ___cxa_find_matching_catch_3() {
var thrown = exceptionLast;
if (!thrown) {
setTempRet0(0);
return 0;
}
var info = new ExceptionInfo(thrown);
info.set_adjusted_ptr(thrown);
var thrownType = info.get_type();
if (!thrownType) {
setTempRet0(0);
return thrown;
}
var typeArray = Array.prototype.slice.call(arguments);
for (var i = 0; i < typeArray.length; i++) {
var caughtType = typeArray[i];
if (caughtType === 0 || caughtType === thrownType) {
break;
}
var adjusted_ptr_addr = info.ptr + 16;
if (___cxa_can_catch(caughtType, thrownType, adjusted_ptr_addr)) {
setTempRet0(caughtType);
return thrown;
}
}
setTempRet0(thrownType);
return thrown;
}
function ___cxa_throw(ptr, type, destructor) {
var info = new ExceptionInfo(ptr);
info.init(type, destructor);
exceptionLast = ptr;
uncaughtExceptionCount++;
throw ptr;
}
function ___emscripten_init_main_thread_js(tb) {
__emscripten_thread_init(tb, !ENVIRONMENT_IS_WORKER, 1, !ENVIRONMENT_IS_WEB);
PThread.threadInitTLS();
}
function ___emscripten_thread_cleanup(thread) {
if (!ENVIRONMENT_IS_PTHREAD) cleanupThread(thread); else postMessage({
"cmd": "cleanupThread",
"thread": thread
});
}
function pthreadCreateProxied(pthread_ptr, attr, start_routine, arg) {
if (ENVIRONMENT_IS_PTHREAD) return _emscripten_proxy_to_main_thread_js(2, 1, pthread_ptr, attr, start_routine, arg);
return ___pthread_create_js(pthread_ptr, attr, start_routine, arg);
}
function ___pthread_create_js(pthread_ptr, attr, start_routine, arg) {
if (typeof SharedArrayBuffer == "undefined") {
err("Current environment does not support SharedArrayBuffer, pthreads are not available!");
return 6;
}
var transferList = [];
var error = 0;
if (ENVIRONMENT_IS_PTHREAD && (transferList.length === 0 || error)) {
return pthreadCreateProxied(pthread_ptr, attr, start_routine, arg);
}
if (error) return error;
var threadParams = {
startRoutine: start_routine,
pthread_ptr: pthread_ptr,
arg: arg,
transferList: transferList
};
if (ENVIRONMENT_IS_PTHREAD) {
threadParams.cmd = "spawnThread";
postMessage(threadParams, transferList);
return 0;
}
return spawnThread(threadParams);
}
var PATH = {
isAbs: path => path.charAt(0) === "/",
splitPath: filename => {
var splitPathRe = /^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/;
return splitPathRe.exec(filename).slice(1);
},
normalizeArray: (parts, allowAboveRoot) => {
var up = 0;
for (var i = parts.length - 1; i >= 0; i--) {
var last = parts[i];
if (last === ".") {
parts.splice(i, 1);
} else if (last === "..") {
parts.splice(i, 1);
up++;
} else if (up) {
parts.splice(i, 1);
up--;
}
}
if (allowAboveRoot) {
for (;up; up--) {
parts.unshift("..");
}
}
return parts;
},
normalize: path => {
var isAbsolute = PATH.isAbs(path), trailingSlash = path.substr(-1) === "/";
path = PATH.normalizeArray(path.split("/").filter(p => !!p), !isAbsolute).join("/");
if (!path && !isAbsolute) {
path = ".";
}
if (path && trailingSlash) {
path += "/";
}
return (isAbsolute ? "/" : "") + path;
},
dirname: path => {
var result = PATH.splitPath(path), root = result[0], dir = result[1];
if (!root && !dir) {
return ".";
}
if (dir) {
dir = dir.substr(0, dir.length - 1);
}
return root + dir;
},
basename: path => {
if (path === "/") return "/";
path = PATH.normalize(path);
path = path.replace(/\/$/, "");
var lastSlash = path.lastIndexOf("/");
if (lastSlash === -1) return path;
return path.substr(lastSlash + 1);
},
join: function() {
var paths = Array.prototype.slice.call(arguments, 0);
return PATH.normalize(paths.join("/"));
},
join2: (l, r) => {
return PATH.normalize(l + "/" + r);
}
};
function getRandomDevice() {
if (typeof crypto == "object" && typeof crypto["getRandomValues"] == "function") {
var randomBuffer = new Uint8Array(1);
return function() {
crypto.getRandomValues(randomBuffer);
return randomBuffer[0];
};
} else if (ENVIRONMENT_IS_NODE) {
try {
var crypto_module = require("crypto");
return function() {
return crypto_module["randomBytes"](1)[0];
};
} catch (e) {}
}
return function() {
abort("randomDevice");
};
}
var PATH_FS = {
resolve: function() {
var resolvedPath = "", resolvedAbsolute = false;
for (var i = arguments.length - 1; i >= -1 && !resolvedAbsolute; i--) {
var path = i >= 0 ? arguments[i] : FS.cwd();
if (typeof path != "string") {
throw new TypeError("Arguments to path.resolve must be strings");
} else if (!path) {
return "";
}
resolvedPath = path + "/" + resolvedPath;
resolvedAbsolute = PATH.isAbs(path);
}
resolvedPath = PATH.normalizeArray(resolvedPath.split("/").filter(p => !!p), !resolvedAbsolute).join("/");
return (resolvedAbsolute ? "/" : "") + resolvedPath || ".";
},
relative: (from, to) => {
from = PATH_FS.resolve(from).substr(1);
to = PATH_FS.resolve(to).substr(1);
function trim(arr) {
var start = 0;
for (;start < arr.length; start++) {
if (arr[start] !== "") break;
}
var end = arr.length - 1;
for (;end >= 0; end--) {
if (arr[end] !== "") break;
}
if (start > end) return [];
return arr.slice(start, end - start + 1);
}
var fromParts = trim(from.split("/"));
var toParts = trim(to.split("/"));
var length = Math.min(fromParts.length, toParts.length);
var samePartsLength = length;
for (var i = 0; i < length; i++) {
if (fromParts[i] !== toParts[i]) {
samePartsLength = i;
break;
}
}
var outputParts = [];
for (var i = samePartsLength; i < fromParts.length; i++) {
outputParts.push("..");
}
outputParts = outputParts.concat(toParts.slice(samePartsLength));
return outputParts.join("/");
}
};
var TTY = {
ttys: [],
init: function() {},
shutdown: function() {},
register: function(dev, ops) {
TTY.ttys[dev] = {
input: [],
output: [],
ops: ops
};
FS.registerDevice(dev, TTY.stream_ops);
},
stream_ops: {
open: function(stream) {
var tty = TTY.ttys[stream.node.rdev];
if (!tty) {
throw new FS.ErrnoError(43);
}
stream.tty = tty;
stream.seekable = false;
},
close: function(stream) {
stream.tty.ops.flush(stream.tty);
},
flush: function(stream) {
stream.tty.ops.flush(stream.tty);
},
read: function(stream, buffer, offset, length, pos) {
if (!stream.tty || !stream.tty.ops.get_char) {
throw new FS.ErrnoError(60);
}
var bytesRead = 0;
for (var i = 0; i < length; i++) {
var result;
try {
result = stream.tty.ops.get_char(stream.tty);
} catch (e) {
throw new FS.ErrnoError(29);
}
if (result === undefined && bytesRead === 0) {
throw new FS.ErrnoError(6);
}
if (result === null || result === undefined) break;
bytesRead++;
buffer[offset + i] = result;
}
if (bytesRead) {
stream.node.timestamp = Date.now();
}
return bytesRead;
},
write: function(stream, buffer, offset, length, pos) {
if (!stream.tty || !stream.tty.ops.put_char) {
throw new FS.ErrnoError(60);
}
try {
for (var i = 0; i < length; i++) {
stream.tty.ops.put_char(stream.tty, buffer[offset + i]);
}
} catch (e) {
throw new FS.ErrnoError(29);
}
if (length) {
stream.node.timestamp = Date.now();
}
return i;
}
},
default_tty_ops: {
get_char: function(tty) {
if (!tty.input.length) {
var result = null;
if (ENVIRONMENT_IS_NODE) {
var BUFSIZE = 256;
var buf = Buffer.alloc(BUFSIZE);
var bytesRead = 0;
try {
bytesRead = fs.readSync(process.stdin.fd, buf, 0, BUFSIZE, -1);
} catch (e) {
if (e.toString().includes("EOF")) bytesRead = 0; else throw e;
}
if (bytesRead > 0) {
result = buf.slice(0, bytesRead).toString("utf-8");
} else {
result = null;
}
} else if (typeof window != "undefined" && typeof window.prompt == "function") {
result = window.prompt("Input: ");
if (result !== null) {
result += "\n";
}
} else if (typeof readline == "function") {
result = readline();
if (result !== null) {
result += "\n";
}
}
if (!result) {
return null;
}
tty.input = intArrayFromString(result, true);
}
return tty.input.shift();
},
put_char: function(tty, val) {
if (val === null || val === 10) {
out(UTF8ArrayToString(tty.output, 0));
tty.output = [];
} else {
if (val != 0) tty.output.push(val);
}
},
flush: function(tty) {
if (tty.output && tty.output.length > 0) {
out(UTF8ArrayToString(tty.output, 0));
tty.output = [];
}
}
},
default_tty1_ops: {
put_char: function(tty, val) {
if (val === null || val === 10) {
err(UTF8ArrayToString(tty.output, 0));
tty.output = [];
} else {
if (val != 0) tty.output.push(val);
}
},
flush: function(tty) {
if (tty.output && tty.output.length > 0) {
err(UTF8ArrayToString(tty.output, 0));
tty.output = [];
}
}
}
};
function alignMemory(size, alignment) {
return Math.ceil(size / alignment) * alignment;
}
function mmapAlloc(size) {
size = alignMemory(size, 65536);
var ptr = _emscripten_builtin_memalign(65536, size);
if (!ptr) return 0;
zeroMemory(ptr, size);
return ptr;
}
var MEMFS = {
ops_table: null,
mount: function(mount) {
return MEMFS.createNode(null, "/", 16384 | 511, 0);
},
createNode: function(parent, name, mode, dev) {
if (FS.isBlkdev(mode) || FS.isFIFO(mode)) {
throw new FS.ErrnoError(63);
}
if (!MEMFS.ops_table) {
MEMFS.ops_table = {
dir: {
node: {
getattr: MEMFS.node_ops.getattr,
setattr: MEMFS.node_ops.setattr,
lookup: MEMFS.node_ops.lookup,
mknod: MEMFS.node_ops.mknod,
rename: MEMFS.node_ops.rename,
unlink: MEMFS.node_ops.unlink,
rmdir: MEMFS.node_ops.rmdir,
readdir: MEMFS.node_ops.readdir,
symlink: MEMFS.node_ops.symlink
},
stream: {
llseek: MEMFS.stream_ops.llseek
}
},
file: {
node: {
getattr: MEMFS.node_ops.getattr,
setattr: MEMFS.node_ops.setattr
},
stream: {
llseek: MEMFS.stream_ops.llseek,
read: MEMFS.stream_ops.read,
write: MEMFS.stream_ops.write,
allocate: MEMFS.stream_ops.allocate,
mmap: MEMFS.stream_ops.mmap,
msync: MEMFS.stream_ops.msync
}
},
link: {
node: {
getattr: MEMFS.node_ops.getattr,
setattr: MEMFS.node_ops.setattr,
readlink: MEMFS.node_ops.readlink
},
stream: {}
},
chrdev: {
node: {
getattr: MEMFS.node_ops.getattr,
setattr: MEMFS.node_ops.setattr
},
stream: FS.chrdev_stream_ops
}
};
}
var node = FS.createNode(parent, name, mode, dev);
if (FS.isDir(node.mode)) {
node.node_ops = MEMFS.ops_table.dir.node;
node.stream_ops = MEMFS.ops_table.dir.stream;
node.contents = {};
} else if (FS.isFile(node.mode)) {
node.node_ops = MEMFS.ops_table.file.node;
node.stream_ops = MEMFS.ops_table.file.stream;
node.usedBytes = 0;
node.contents = null;
} else if (FS.isLink(node.mode)) {
node.node_ops = MEMFS.ops_table.link.node;
node.stream_ops = MEMFS.ops_table.link.stream;
} else if (FS.isChrdev(node.mode)) {
node.node_ops = MEMFS.ops_table.chrdev.node;
node.stream_ops = MEMFS.ops_table.chrdev.stream;
}
node.timestamp = Date.now();
if (parent) {
parent.contents[name] = node;
parent.timestamp = node.timestamp;
}
return node;
},
getFileDataAsTypedArray: function(node) {
if (!node.contents) return new Uint8Array(0);
if (node.contents.subarray) return node.contents.subarray(0, node.usedBytes);
return new Uint8Array(node.contents);
},
expandFileStorage: function(node, newCapacity) {
var prevCapacity = node.contents ? node.contents.length : 0;
if (prevCapacity >= newCapacity) return;
var CAPACITY_DOUBLING_MAX = 1024 * 1024;
newCapacity = Math.max(newCapacity, prevCapacity * (prevCapacity < CAPACITY_DOUBLING_MAX ? 2 : 1.125) >>> 0);
if (prevCapacity != 0) newCapacity = Math.max(newCapacity, 256);
var oldContents = node.contents;
node.contents = new Uint8Array(newCapacity);
if (node.usedBytes > 0) node.contents.set(oldContents.subarray(0, node.usedBytes), 0);
},
resizeFileStorage: function(node, newSize) {
if (node.usedBytes == newSize) return;
if (newSize == 0) {
node.contents = null;
node.usedBytes = 0;
} else {
var oldContents = node.contents;
node.contents = new Uint8Array(newSize);
if (oldContents) {
node.contents.set(oldContents.subarray(0, Math.min(newSize, node.usedBytes)));
}
node.usedBytes = newSize;
}
},
node_ops: {
getattr: function(node) {
var attr = {};
attr.dev = FS.isChrdev(node.mode) ? node.id : 1;
attr.ino = node.id;
attr.mode = node.mode;
attr.nlink = 1;
attr.uid = 0;
attr.gid = 0;
attr.rdev = node.rdev;
if (FS.isDir(node.mode)) {
attr.size = 4096;
} else if (FS.isFile(node.mode)) {
attr.size = node.usedBytes;
} else if (FS.isLink(node.mode)) {
attr.size = node.link.length;
} else {
attr.size = 0;
}
attr.atime = new Date(node.timestamp);
attr.mtime = new Date(node.timestamp);
attr.ctime = new Date(node.timestamp);
attr.blksize = 4096;
attr.blocks = Math.ceil(attr.size / attr.blksize);
return attr;
},
setattr: function(node, attr) {
if (attr.mode !== undefined) {
node.mode = attr.mode;
}
if (attr.timestamp !== undefined) {
node.timestamp = attr.timestamp;
}
if (attr.size !== undefined) {
MEMFS.resizeFileStorage(node, attr.size);
}
},
lookup: function(parent, name) {
throw FS.genericErrors[44];
},
mknod: function(parent, name, mode, dev) {
return MEMFS.createNode(parent, name, mode, dev);
},
rename: function(old_node, new_dir, new_name) {
if (FS.isDir(old_node.mode)) {
var new_node;
try {
new_node = FS.lookupNode(new_dir, new_name);
} catch (e) {}
if (new_node) {
for (var i in new_node.contents) {
throw new FS.ErrnoError(55);
}
}
}
delete old_node.parent.contents[old_node.name];
old_node.parent.timestamp = Date.now();
old_node.name = new_name;
new_dir.contents[new_name] = old_node;
new_dir.timestamp = old_node.parent.timestamp;
old_node.parent = new_dir;
},
unlink: function(parent, name) {
delete parent.contents[name];
parent.timestamp = Date.now();
},
rmdir: function(parent, name) {
var node = FS.lookupNode(parent, name);
for (var i in node.contents) {
throw new FS.ErrnoError(55);
}
delete parent.contents[name];
parent.timestamp = Date.now();
},
readdir: function(node) {
var entries = [ ".", ".." ];
for (var key in node.contents) {
if (!node.contents.hasOwnProperty(key)) {
continue;
}
entries.push(key);
}
return entries;
},
symlink: function(parent, newname, oldpath) {
var node = MEMFS.createNode(parent, newname, 511 | 40960, 0);
node.link = oldpath;
return node;
},
readlink: function(node) {
if (!FS.isLink(node.mode)) {
throw new FS.ErrnoError(28);
}
return node.link;
}
},
stream_ops: {
read: function(stream, buffer, offset, length, position) {
var contents = stream.node.contents;
if (position >= stream.node.usedBytes) return 0;
var size = Math.min(stream.node.usedBytes - position, length);
if (size > 8 && contents.subarray) {
buffer.set(contents.subarray(position, position + size), offset);
} else {
for (var i = 0; i < size; i++) buffer[offset + i] = contents[position + i];
}
return size;
},
write: function(stream, buffer, offset, length, position, canOwn) {
if (buffer.buffer === GROWABLE_HEAP_I8().buffer) {
canOwn = false;
}
if (!length) return 0;
var node = stream.node;
node.timestamp = Date.now();
if (buffer.subarray && (!node.contents || node.contents.subarray)) {
if (canOwn) {
node.contents = buffer.subarray(offset, offset + length);
node.usedBytes = length;
return length;
} else if (node.usedBytes === 0 && position === 0) {
node.contents = buffer.slice(offset, offset + length);
node.usedBytes = length;
return length;
} else if (position + length <= node.usedBytes) {
node.contents.set(buffer.subarray(offset, offset + length), position);
return length;
}
}
MEMFS.expandFileStorage(node, position + length);
if (node.contents.subarray && buffer.subarray) {
node.contents.set(buffer.subarray(offset, offset + length), position);
} else {
for (var i = 0; i < length; i++) {
node.contents[position + i] = buffer[offset + i];
}
}
node.usedBytes = Math.max(node.usedBytes, position + length);
return length;
},
llseek: function(stream, offset, whence) {
var position = offset;
if (whence === 1) {
position += stream.position;
} else if (whence === 2) {
if (FS.isFile(stream.node.mode)) {
position += stream.node.usedBytes;
}
}
if (position < 0) {
throw new FS.ErrnoError(28);
}
return position;
},
allocate: function(stream, offset, length) {
MEMFS.expandFileStorage(stream.node, offset + length);
stream.node.usedBytes = Math.max(stream.node.usedBytes, offset + length);
},
mmap: function(stream, length, position, prot, flags) {
if (!FS.isFile(stream.node.mode)) {
throw new FS.ErrnoError(43);
}
var ptr;
var allocated;
var contents = stream.node.contents;
if (!(flags & 2) && contents.buffer === buffer) {
allocated = false;
ptr = contents.byteOffset;
} else {
if (position > 0 || position + length < contents.length) {
if (contents.subarray) {
contents = contents.subarray(position, position + length);
} else {
contents = Array.prototype.slice.call(contents, position, position + length);
}
}
allocated = true;
ptr = mmapAlloc(length);
if (!ptr) {
throw new FS.ErrnoError(48);
}
GROWABLE_HEAP_I8().set(contents, ptr);
}
return {
ptr: ptr,
allocated: allocated
};
},
msync: function(stream, buffer, offset, length, mmapFlags) {
if (!FS.isFile(stream.node.mode)) {
throw new FS.ErrnoError(43);
}
if (mmapFlags & 2) {
return 0;
}
var bytesWritten = MEMFS.stream_ops.write(stream, buffer, 0, length, offset, false);
return 0;
}
}
};
function asyncLoad(url, onload, onerror, noRunDep) {
var dep = !noRunDep ? getUniqueRunDependency("al " + url) : "";
readAsync(url, function(arrayBuffer) {
assert(arrayBuffer, 'Loading data file "' + url + '" failed (no arrayBuffer).');
onload(new Uint8Array(arrayBuffer));
if (dep) removeRunDependency(dep);
}, function(event) {
if (onerror) {
onerror();
} else {
throw 'Loading data file "' + url + '" failed.';
}
});
if (dep) addRunDependency(dep);
}
var FS = {
root: null,
mounts: [],
devices: {},
streams: [],
nextInode: 1,
nameTable: null,
currentPath: "/",
initialized: false,
ignorePermissions: true,
ErrnoError: null,
genericErrors: {},
filesystems: null,
syncFSRequests: 0,
lookupPath: (path, opts = {}) => {
path = PATH_FS.resolve(FS.cwd(), path);
if (!path) return {
path: "",
node: null
};
var defaults = {
follow_mount: true,
recurse_count: 0
};
opts = Object.assign(defaults, opts);
if (opts.recurse_count > 8) {
throw new FS.ErrnoError(32);
}
var parts = PATH.normalizeArray(path.split("/").filter(p => !!p), false);
var current = FS.root;
var current_path = "/";
for (var i = 0; i < parts.length; i++) {
var islast = i === parts.length - 1;
if (islast && opts.parent) {
break;
}
current = FS.lookupNode(current, parts[i]);
current_path = PATH.join2(current_path, parts[i]);
if (FS.isMountpoint(current)) {
if (!islast || islast && opts.follow_mount) {
current = current.mounted.root;
}
}
if (!islast || opts.follow) {
var count = 0;
while (FS.isLink(current.mode)) {
var link = FS.readlink(current_path);
current_path = PATH_FS.resolve(PATH.dirname(current_path), link);
var lookup = FS.lookupPath(current_path, {
recurse_count: opts.recurse_count + 1
});
current = lookup.node;
if (count++ > 40) {
throw new FS.ErrnoError(32);
}
}
}
}
return {
path: current_path,
node: current
};
},
getPath: node => {
var path;
while (true) {
if (FS.isRoot(node)) {
var mount = node.mount.mountpoint;
if (!path) return mount;
return mount[mount.length - 1] !== "/" ? mount + "/" + path : mount + path;
}
path = path ? node.name + "/" + path : node.name;
node = node.parent;
}
},
hashName: (parentid, name) => {
var hash = 0;
for (var i = 0; i < name.length; i++) {
hash = (hash << 5) - hash + name.charCodeAt(i) | 0;
}
return (parentid + hash >>> 0) % FS.nameTable.length;
},
hashAddNode: node => {
var hash = FS.hashName(node.parent.id, node.name);
node.name_next = FS.nameTable[hash];
FS.nameTable[hash] = node;
},
hashRemoveNode: node => {
var hash = FS.hashName(node.parent.id, node.name);
if (FS.nameTable[hash] === node) {
FS.nameTable[hash] = node.name_next;
} else {
var current = FS.nameTable[hash];
while (current) {
if (current.name_next === node) {
current.name_next = node.name_next;
break;
}
current = current.name_next;
}
}
},
lookupNode: (parent, name) => {
var errCode = FS.mayLookup(parent);
if (errCode) {
throw new FS.ErrnoError(errCode, parent);
}
var hash = FS.hashName(parent.id, name);
for (var node = FS.nameTable[hash]; node; node = node.name_next) {
var nodeName = node.name;
if (node.parent.id === parent.id && nodeName === name) {
return node;
}
}
return FS.lookup(parent, name);
},
createNode: (parent, name, mode, rdev) => {
var node = new FS.FSNode(parent, name, mode, rdev);
FS.hashAddNode(node);
return node;
},
destroyNode: node => {
FS.hashRemoveNode(node);
},
isRoot: node => {
return node === node.parent;
},
isMountpoint: node => {
return !!node.mounted;
},
isFile: mode => {
return (mode & 61440) === 32768;
},
isDir: mode => {
return (mode & 61440) === 16384;
},
isLink: mode => {
return (mode & 61440) === 40960;
},
isChrdev: mode => {
return (mode & 61440) === 8192;
},
isBlkdev: mode => {
return (mode & 61440) === 24576;
},
isFIFO: mode => {
return (mode & 61440) === 4096;
},
isSocket: mode => {
return (mode & 49152) === 49152;
},
flagModes: {
"r": 0,
"r+": 2,
"w": 577,
"w+": 578,
"a": 1089,
"a+": 1090
},
modeStringToFlags: str => {
var flags = FS.flagModes[str];
if (typeof flags == "undefined") {
throw new Error("Unknown file open mode: " + str);
}
return flags;
},
flagsToPermissionString: flag => {
var perms = [ "r", "w", "rw" ][flag & 3];
if (flag & 512) {
perms += "w";
}
return perms;
},
nodePermissions: (node, perms) => {
if (FS.ignorePermissions) {
return 0;
}
if (perms.includes("r") && !(node.mode & 292)) {
return 2;
} else if (perms.includes("w") && !(node.mode & 146)) {
return 2;
} else if (perms.includes("x") && !(node.mode & 73)) {
return 2;
}
return 0;
},
mayLookup: dir => {
var errCode = FS.nodePermissions(dir, "x");
if (errCode) return errCode;
if (!dir.node_ops.lookup) return 2;
return 0;
},
mayCreate: (dir, name) => {
try {
var node = FS.lookupNode(dir, name);
return 20;
} catch (e) {}
return FS.nodePermissions(dir, "wx");
},
mayDelete: (dir, name, isdir) => {
var node;
try {
node = FS.lookupNode(dir, name);
} catch (e) {
return e.errno;
}
var errCode = FS.nodePermissions(dir, "wx");
if (errCode) {
return errCode;
}
if (isdir) {
if (!FS.isDir(node.mode)) {
return 54;
}
if (FS.isRoot(node) || FS.getPath(node) === FS.cwd()) {
return 10;
}
} else {
if (FS.isDir(node.mode)) {
return 31;
}
}
return 0;
},
mayOpen: (node, flags) => {
if (!node) {
return 44;
}
if (FS.isLink(node.mode)) {
return 32;
} else if (FS.isDir(node.mode)) {
if (FS.flagsToPermissionString(flags) !== "r" || flags & 512) {
return 31;
}
}
return FS.nodePermissions(node, FS.flagsToPermissionString(flags));
},
MAX_OPEN_FDS: 4096,
nextfd: (fd_start = 0, fd_end = FS.MAX_OPEN_FDS) => {
for (var fd = fd_start; fd <= fd_end; fd++) {
if (!FS.streams[fd]) {
return fd;
}
}
throw new FS.ErrnoError(33);
},
getStream: fd => FS.streams[fd],
createStream: (stream, fd_start, fd_end) => {
if (!FS.FSStream) {
FS.FSStream = function() {
this.shared = {};
};
FS.FSStream.prototype = {
object: {
get: function() {
return this.node;
},
set: function(val) {
this.node = val;
}
},
isRead: {
get: function() {
return (this.flags & 2097155) !== 1;
}
},
isWrite: {
get: function() {
return (this.flags & 2097155) !== 0;
}
},
isAppend: {
get: function() {
return this.flags & 1024;
}
},
flags: {
get: function() {
return this.shared.flags;
},
set: function(val) {
this.shared.flags = val;
}
},
position: {
get function() {
return this.shared.position;
},
set: function(val) {
this.shared.position = val;
}
}
};
}
stream = Object.assign(new FS.FSStream(), stream);
var fd = FS.nextfd(fd_start, fd_end);
stream.fd = fd;
FS.streams[fd] = stream;
return stream;
},
closeStream: fd => {
FS.streams[fd] = null;
},
chrdev_stream_ops: {
open: stream => {
var device = FS.getDevice(stream.node.rdev);
stream.stream_ops = device.stream_ops;
if (stream.stream_ops.open) {
stream.stream_ops.open(stream);
}
},
llseek: () => {
throw new FS.ErrnoError(70);
}
},
major: dev => dev >> 8,
minor: dev => dev & 255,
makedev: (ma, mi) => ma << 8 | mi,
registerDevice: (dev, ops) => {
FS.devices[dev] = {
stream_ops: ops
};
},
getDevice: dev => FS.devices[dev],
getMounts: mount => {
var mounts = [];
var check = [ mount ];
while (check.length) {
var m = check.pop();
mounts.push(m);
check.push.apply(check, m.mounts);
}
return mounts;
},
syncfs: (populate, callback) => {
if (typeof populate == "function") {
callback = populate;
populate = false;
}
FS.syncFSRequests++;
if (FS.syncFSRequests > 1) {
err("warning: " + FS.syncFSRequests + " FS.syncfs operations in flight at once, probably just doing extra work");
}
var mounts = FS.getMounts(FS.root.mount);
var completed = 0;
function doCallback(errCode) {
FS.syncFSRequests--;
return callback(errCode);
}
function done(errCode) {
if (errCode) {
if (!done.errored) {
done.errored = true;
return doCallback(errCode);
}
return;
}
if (++completed >= mounts.length) {
doCallback(null);
}
}
mounts.forEach(mount => {
if (!mount.type.syncfs) {
return done(null);
}
mount.type.syncfs(mount, populate, done);
});
},
mount: (type, opts, mountpoint) => {
var root = mountpoint === "/";
var pseudo = !mountpoint;
var node;
if (root && FS.root) {
throw new FS.ErrnoError(10);
} else if (!root && !pseudo) {
var lookup = FS.lookupPath(mountpoint, {
follow_mount: false
});
mountpoint = lookup.path;
node = lookup.node;
if (FS.isMountpoint(node)) {
throw new FS.ErrnoError(10);
}
if (!FS.isDir(node.mode)) {
throw new FS.ErrnoError(54);
}
}
var mount = {
type: type,
opts: opts,
mountpoint: mountpoint,
mounts: []
};
var mountRoot = type.mount(mount);
mountRoot.mount = mount;
mount.root = mountRoot;
if (root) {
FS.root = mountRoot;
} else if (node) {
node.mounted = mount;
if (node.mount) {
node.mount.mounts.push(mount);
}
}
return mountRoot;
},
unmount: mountpoint => {
var lookup = FS.lookupPath(mountpoint, {
follow_mount: false
});
if (!FS.isMountpoint(lookup.node)) {
throw new FS.ErrnoError(28);
}
var node = lookup.node;
var mount = node.mounted;
var mounts = FS.getMounts(mount);
Object.keys(FS.nameTable).forEach(hash => {
var current = FS.nameTable[hash];
while (current) {
var next = current.name_next;
if (mounts.includes(current.mount)) {
FS.destroyNode(current);
}
current = next;
}
});
node.mounted = null;
var idx = node.mount.mounts.indexOf(mount);
node.mount.mounts.splice(idx, 1);
},
lookup: (parent, name) => {
return parent.node_ops.lookup(parent, name);
},
mknod: (path, mode, dev) => {
var lookup = FS.lookupPath(path, {
parent: true
});
var parent = lookup.node;
var name = PATH.basename(path);
if (!name || name === "." || name === "..") {
throw new FS.ErrnoError(28);
}
var errCode = FS.mayCreate(parent, name);
if (errCode) {
throw new FS.ErrnoError(errCode);
}
if (!parent.node_ops.mknod) {
throw new FS.ErrnoError(63);
}
return parent.node_ops.mknod(parent, name, mode, dev);
},
create: (path, mode) => {
mode = mode !== undefined ? mode : 438;
mode &= 4095;
mode |= 32768;
return FS.mknod(path, mode, 0);
},
mkdir: (path, mode) => {
mode = mode !== undefined ? mode : 511;
mode &= 511 | 512;
mode |= 16384;
return FS.mknod(path, mode, 0);
},
mkdirTree: (path, mode) => {
var dirs = path.split("/");
var d = "";
for (var i = 0; i < dirs.length; ++i) {
if (!dirs[i]) continue;
d += "/" + dirs[i];
try {
FS.mkdir(d, mode);
} catch (e) {
if (e.errno != 20) throw e;
}
}
},
mkdev: (path, mode, dev) => {
if (typeof dev == "undefined") {
dev = mode;
mode = 438;
}
mode |= 8192;
return FS.mknod(path, mode, dev);
},
symlink: (oldpath, newpath) => {
if (!PATH_FS.resolve(oldpath)) {
throw new FS.ErrnoError(44);
}
var lookup = FS.lookupPath(newpath, {
parent: true
});
var parent = lookup.node;
if (!parent) {
throw new FS.ErrnoError(44);
}
var newname = PATH.basename(newpath);
var errCode = FS.mayCreate(parent, newname);
if (errCode) {
throw new FS.ErrnoError(errCode);
}
if (!parent.node_ops.symlink) {
throw new FS.ErrnoError(63);
}
return parent.node_ops.symlink(parent, newname, oldpath);
},
rename: (old_path, new_path) => {
var old_dirname = PATH.dirname(old_path);
var new_dirname = PATH.dirname(new_path);
var old_name = PATH.basename(old_path);
var new_name = PATH.basename(new_path);
var lookup, old_dir, new_dir;
lookup = FS.lookupPath(old_path, {
parent: true
});
old_dir = lookup.node;
lookup = FS.lookupPath(new_path, {
parent: true
});
new_dir = lookup.node;
if (!old_dir || !new_dir) throw new FS.ErrnoError(44);
if (old_dir.mount !== new_dir.mount) {
throw new FS.ErrnoError(75);
}
var old_node = FS.lookupNode(old_dir, old_name);
var relative = PATH_FS.relative(old_path, new_dirname);
if (relative.charAt(0) !== ".") {
throw new FS.ErrnoError(28);
}
relative = PATH_FS.relative(new_path, old_dirname);
if (relative.charAt(0) !== ".") {
throw new FS.ErrnoError(55);
}
var new_node;
try {
new_node = FS.lookupNode(new_dir, new_name);
} catch (e) {}
if (old_node === new_node) {
return;
}
var isdir = FS.isDir(old_node.mode);
var errCode = FS.mayDelete(old_dir, old_name, isdir);
if (errCode) {
throw new FS.ErrnoError(errCode);
}
errCode = new_node ? FS.mayDelete(new_dir, new_name, isdir) : FS.mayCreate(new_dir, new_name);
if (errCode) {
throw new FS.ErrnoError(errCode);
}
if (!old_dir.node_ops.rename) {
throw new FS.ErrnoError(63);
}
if (FS.isMountpoint(old_node) || new_node && FS.isMountpoint(new_node)) {
throw new FS.ErrnoError(10);
}
if (new_dir !== old_dir) {
errCode = FS.nodePermissions(old_dir, "w");
if (errCode) {
throw new FS.ErrnoError(errCode);
}
}
FS.hashRemoveNode(old_node);
try {
old_dir.node_ops.rename(old_node, new_dir, new_name);
} catch (e) {
throw e;
} finally {
FS.hashAddNode(old_node);
}
},
rmdir: path => {
var lookup = FS.lookupPath(path, {
parent: true
});
var parent = lookup.node;
var name = PATH.basename(path);
var node = FS.lookupNode(parent, name);
var errCode = FS.mayDelete(parent, name, true);
if (errCode) {
throw new FS.ErrnoError(errCode);
}
if (!parent.node_ops.rmdir) {
throw new FS.ErrnoError(63);
}
if (FS.isMountpoint(node)) {
throw new FS.ErrnoError(10);
}
parent.node_ops.rmdir(parent, name);
FS.destroyNode(node);
},
readdir: path => {
var lookup = FS.lookupPath(path, {
follow: true
});
var node = lookup.node;
if (!node.node_ops.readdir) {
throw new FS.ErrnoError(54);
}
return node.node_ops.readdir(node);
},
unlink: path => {
var lookup = FS.lookupPath(path, {
parent: true
});
var parent = lookup.node;
if (!parent) {
throw new FS.ErrnoError(44);
}
var name = PATH.basename(path);
var node = FS.lookupNode(parent, name);
var errCode = FS.mayDelete(parent, name, false);
if (errCode) {
throw new FS.ErrnoError(errCode);
}
if (!parent.node_ops.unlink) {
throw new FS.ErrnoError(63);
}
if (FS.isMountpoint(node)) {
throw new FS.ErrnoError(10);
}
parent.node_ops.unlink(parent, name);
FS.destroyNode(node);
},
readlink: path => {
var lookup = FS.lookupPath(path);
var link = lookup.node;
if (!link) {
throw new FS.ErrnoError(44);
}
if (!link.node_ops.readlink) {
throw new FS.ErrnoError(28);
}
return PATH_FS.resolve(FS.getPath(link.parent), link.node_ops.readlink(link));
},
stat: (path, dontFollow) => {
var lookup = FS.lookupPath(path, {
follow: !dontFollow
});
var node = lookup.node;
if (!node) {
throw new FS.ErrnoError(44);
}
if (!node.node_ops.getattr) {
throw new FS.ErrnoError(63);
}
return node.node_ops.getattr(node);
},
lstat: path => {
return FS.stat(path, true);
},
chmod: (path, mode, dontFollow) => {
var node;
if (typeof path == "string") {
var lookup = FS.lookupPath(path, {
follow: !dontFollow
});
node = lookup.node;
} else {
node = path;
}
if (!node.node_ops.setattr) {
throw new FS.ErrnoError(63);
}
node.node_ops.setattr(node, {
mode: mode & 4095 | node.mode & ~4095,
timestamp: Date.now()
});
},
lchmod: (path, mode) => {
FS.chmod(path, mode, true);
},
fchmod: (fd, mode) => {
var stream = FS.getStream(fd);
if (!stream) {
throw new FS.ErrnoError(8);
}
FS.chmod(stream.node, mode);
},
chown: (path, uid, gid, dontFollow) => {
var node;
if (typeof path == "string") {
var lookup = FS.lookupPath(path, {
follow: !dontFollow
});
node = lookup.node;
} else {
node = path;
}
if (!node.node_ops.setattr) {
throw new FS.ErrnoError(63);
}
node.node_ops.setattr(node, {
timestamp: Date.now()
});
},
lchown: (path, uid, gid) => {
FS.chown(path, uid, gid, true);
},
fchown: (fd, uid, gid) => {
var stream = FS.getStream(fd);
if (!stream) {
throw new FS.ErrnoError(8);
}
FS.chown(stream.node, uid, gid);
},
truncate: (path, len) => {
if (len < 0) {
throw new FS.ErrnoError(28);
}
var node;
if (typeof path == "string") {
var lookup = FS.lookupPath(path, {
follow: true
});
node = lookup.node;
} else {
node = path;
}
if (!node.node_ops.setattr) {
throw new FS.ErrnoError(63);
}
if (FS.isDir(node.mode)) {
throw new FS.ErrnoError(31);
}
if (!FS.isFile(node.mode)) {
throw new FS.ErrnoError(28);
}
var errCode = FS.nodePermissions(node, "w");
if (errCode) {
throw new FS.ErrnoError(errCode);
}
node.node_ops.setattr(node, {
size: len,
timestamp: Date.now()
});
},
ftruncate: (fd, len) => {
var stream = FS.getStream(fd);
if (!stream) {
throw new FS.ErrnoError(8);
}
if ((stream.flags & 2097155) === 0) {
throw new FS.ErrnoError(28);
}
FS.truncate(stream.node, len);
},
utime: (path, atime, mtime) => {
var lookup = FS.lookupPath(path, {
follow: true
});
var node = lookup.node;
node.node_ops.setattr(node, {
timestamp: Math.max(atime, mtime)
});
},
open: (path, flags, mode) => {
if (path === "") {
throw new FS.ErrnoError(44);
}
flags = typeof flags == "string" ? FS.modeStringToFlags(flags) : flags;
mode = typeof mode == "undefined" ? 438 : mode;
if (flags & 64) {
mode = mode & 4095 | 32768;
} else {
mode = 0;
}
var node;
if (typeof path == "object") {
node = path;
} else {
path = PATH.normalize(path);
try {
var lookup = FS.lookupPath(path, {
follow: !(flags & 131072)
});
node = lookup.node;
} catch (e) {}
}
var created = false;
if (flags & 64) {
if (node) {
if (flags & 128) {
throw new FS.ErrnoError(20);
}
} else {
node = FS.mknod(path, mode, 0);
created = true;
}
}
if (!node) {
throw new FS.ErrnoError(44);
}
if (FS.isChrdev(node.mode)) {
flags &= ~512;
}
if (flags & 65536 && !FS.isDir(node.mode)) {
throw new FS.ErrnoError(54);
}
if (!created) {
var errCode = FS.mayOpen(node, flags);
if (errCode) {
throw new FS.ErrnoError(errCode);
}
}
if (flags & 512 && !created) {
FS.truncate(node, 0);
}
flags &= ~(128 | 512 | 131072);
var stream = FS.createStream({
node: node,
path: FS.getPath(node),
flags: flags,
seekable: true,
position: 0,
stream_ops: node.stream_ops,
ungotten: [],
error: false
});
if (stream.stream_ops.open) {
stream.stream_ops.open(stream);
}
if (Module["logReadFiles"] && !(flags & 1)) {
if (!FS.readFiles) FS.readFiles = {};
if (!(path in FS.readFiles)) {
FS.readFiles[path] = 1;
}
}
return stream;
},
close: stream => {
if (FS.isClosed(stream)) {
throw new FS.ErrnoError(8);
}
if (stream.getdents) stream.getdents = null;
try {
if (stream.stream_ops.close) {
stream.stream_ops.close(stream);
}
} catch (e) {
throw e;
} finally {
FS.closeStream(stream.fd);
}
stream.fd = null;
},
isClosed: stream => {
return stream.fd === null;
},
llseek: (stream, offset, whence) => {
if (FS.isClosed(stream)) {
throw new FS.ErrnoError(8);
}
if (!stream.seekable || !stream.stream_ops.llseek) {
throw new FS.ErrnoError(70);
}
if (whence != 0 && whence != 1 && whence != 2) {
throw new FS.ErrnoError(28);
}
stream.position = stream.stream_ops.llseek(stream, offset, whence);
stream.ungotten = [];
return stream.position;
},
read: (stream, buffer, offset, length, position) => {
if (length < 0 || position < 0) {
throw new FS.ErrnoError(28);
}
if (FS.isClosed(stream)) {
throw new FS.ErrnoError(8);
}
if ((stream.flags & 2097155) === 1) {
throw new FS.ErrnoError(8);
}
if (FS.isDir(stream.node.mode)) {
throw new FS.ErrnoError(31);
}
if (!stream.stream_ops.read) {
throw new FS.ErrnoError(28);
}
var seeking = typeof position != "undefined";
if (!seeking) {
position = stream.position;
} else if (!stream.seekable) {
throw new FS.ErrnoError(70);
}
var bytesRead = stream.stream_ops.read(stream, buffer, offset, length, position);
if (!seeking) stream.position += bytesRead;
return bytesRead;
},
write: (stream, buffer, offset, length, position, canOwn) => {
if (length < 0 || position < 0) {
throw new FS.ErrnoError(28);
}
if (FS.isClosed(stream)) {
throw new FS.ErrnoError(8);
}
if ((stream.flags & 2097155) === 0) {
throw new FS.ErrnoError(8);
}
if (FS.isDir(stream.node.mode)) {
throw new FS.ErrnoError(31);
}
if (!stream.stream_ops.write) {
throw new FS.ErrnoError(28);
}
if (stream.seekable && stream.flags & 1024) {
FS.llseek(stream, 0, 2);
}
var seeking = typeof position != "undefined";
if (!seeking) {
position = stream.position;
} else if (!stream.seekable) {
throw new FS.ErrnoError(70);
}
var bytesWritten = stream.stream_ops.write(stream, buffer, offset, length, position, canOwn);
if (!seeking) stream.position += bytesWritten;
return bytesWritten;
},
allocate: (stream, offset, length) => {
if (FS.isClosed(stream)) {
throw new FS.ErrnoError(8);
}
if (offset < 0 || length <= 0) {
throw new FS.ErrnoError(28);
}
if ((stream.flags & 2097155) === 0) {
throw new FS.ErrnoError(8);
}
if (!FS.isFile(stream.node.mode) && !FS.isDir(stream.node.mode)) {
throw new FS.ErrnoError(43);
}
if (!stream.stream_ops.allocate) {
throw new FS.ErrnoError(138);
}
stream.stream_ops.allocate(stream, offset, length);
},
mmap: (stream, length, position, prot, flags) => {
if ((prot & 2) !== 0 && (flags & 2) === 0 && (stream.flags & 2097155) !== 2) {
throw new FS.ErrnoError(2);
}
if ((stream.flags & 2097155) === 1) {
throw new FS.ErrnoError(2);
}
if (!stream.stream_ops.mmap) {
throw new FS.ErrnoError(43);
}
return stream.stream_ops.mmap(stream, length, position, prot, flags);
},
msync: (stream, buffer, offset, length, mmapFlags) => {
if (!stream || !stream.stream_ops.msync) {
return 0;
}
return stream.stream_ops.msync(stream, buffer, offset, length, mmapFlags);
},
munmap: stream => 0,
ioctl: (stream, cmd, arg) => {
if (!stream.stream_ops.ioctl) {
throw new FS.ErrnoError(59);
}
return stream.stream_ops.ioctl(stream, cmd, arg);
},
readFile: (path, opts = {}) => {
opts.flags = opts.flags || 0;
opts.encoding = opts.encoding || "binary";
if (opts.encoding !== "utf8" && opts.encoding !== "binary") {
throw new Error('Invalid encoding type "' + opts.encoding + '"');
}
var ret;
var stream = FS.open(path, opts.flags);
var stat = FS.stat(path);
var length = stat.size;
var buf = new Uint8Array(length);
FS.read(stream, buf, 0, length, 0);
if (opts.encoding === "utf8") {
ret = UTF8ArrayToString(buf, 0);
} else if (opts.encoding === "binary") {
ret = buf;
}
FS.close(stream);
return ret;
},
writeFile: (path, data, opts = {}) => {
opts.flags = opts.flags || 577;
var stream = FS.open(path, opts.flags, opts.mode);
if (typeof data == "string") {
var buf = new Uint8Array(lengthBytesUTF8(data) + 1);
var actualNumBytes = stringToUTF8Array(data, buf, 0, buf.length);
FS.write(stream, buf, 0, actualNumBytes, undefined, opts.canOwn);
} else if (ArrayBuffer.isView(data)) {
FS.write(stream, data, 0, data.byteLength, undefined, opts.canOwn);
} else {
throw new Error("Unsupported data type");
}
FS.close(stream);
},
cwd: () => FS.currentPath,
chdir: path => {
var lookup = FS.lookupPath(path, {
follow: true
});
if (lookup.node === null) {
throw new FS.ErrnoError(44);
}
if (!FS.isDir(lookup.node.mode)) {
throw new FS.ErrnoError(54);
}
var errCode = FS.nodePermissions(lookup.node, "x");
if (errCode) {
throw new FS.ErrnoError(errCode);
}
FS.currentPath = lookup.path;
},
createDefaultDirectories: () => {
FS.mkdir("/tmp");
FS.mkdir("/home");
FS.mkdir("/home/web_user");
},
createDefaultDevices: () => {
FS.mkdir("/dev");
FS.registerDevice(FS.makedev(1, 3), {
read: () => 0,
write: (stream, buffer, offset, length, pos) => length
});
FS.mkdev("/dev/null", FS.makedev(1, 3));
TTY.register(FS.makedev(5, 0), TTY.default_tty_ops);
TTY.register(FS.makedev(6, 0), TTY.default_tty1_ops);
FS.mkdev("/dev/tty", FS.makedev(5, 0));
FS.mkdev("/dev/tty1", FS.makedev(6, 0));
var random_device = getRandomDevice();
FS.createDevice("/dev", "random", random_device);
FS.createDevice("/dev", "urandom", random_device);
FS.mkdir("/dev/shm");
FS.mkdir("/dev/shm/tmp");
},
createSpecialDirectories: () => {
FS.mkdir("/proc");
var proc_self = FS.mkdir("/proc/self");
FS.mkdir("/proc/self/fd");
FS.mount({
mount: () => {
var node = FS.createNode(proc_self, "fd", 16384 | 511, 73);
node.node_ops = {
lookup: (parent, name) => {
var fd = +name;
var stream = FS.getStream(fd);
if (!stream) throw new FS.ErrnoError(8);
var ret = {
parent: null,
mount: {
mountpoint: "fake"
},
node_ops: {
readlink: () => stream.path
}
};
ret.parent = ret;
return ret;
}
};
return node;
}
}, {}, "/proc/self/fd");
},
createStandardStreams: () => {
if (Module["stdin"]) {
FS.createDevice("/dev", "stdin", Module["stdin"]);
} else {
FS.symlink("/dev/tty", "/dev/stdin");
}
if (Module["stdout"]) {
FS.createDevice("/dev", "stdout", null, Module["stdout"]);
} else {
FS.symlink("/dev/tty", "/dev/stdout");
}
if (Module["stderr"]) {
FS.createDevice("/dev", "stderr", null, Module["stderr"]);
} else {
FS.symlink("/dev/tty1", "/dev/stderr");
}
var stdin = FS.open("/dev/stdin", 0);
var stdout = FS.open("/dev/stdout", 1);
var stderr = FS.open("/dev/stderr", 1);
},
ensureErrnoError: () => {
if (FS.ErrnoError) return;
FS.ErrnoError = function ErrnoError(errno, node) {
this.node = node;
this.setErrno = function(errno) {
this.errno = errno;
};
this.setErrno(errno);
this.message = "FS error";
};
FS.ErrnoError.prototype = new Error();
FS.ErrnoError.prototype.constructor = FS.ErrnoError;
[ 44 ].forEach(code => {
FS.genericErrors[code] = new FS.ErrnoError(code);
FS.genericErrors[code].stack = "<generic error, no stack>";
});
},
staticInit: () => {
FS.ensureErrnoError();
FS.nameTable = new Array(4096);
FS.mount(MEMFS, {}, "/");
FS.createDefaultDirectories();
FS.createDefaultDevices();
FS.createSpecialDirectories();
FS.filesystems = {
"MEMFS": MEMFS
};
},
init: (input, output, error) => {
FS.init.initialized = true;
FS.ensureErrnoError();
Module["stdin"] = input || Module["stdin"];
Module["stdout"] = output || Module["stdout"];
Module["stderr"] = error || Module["stderr"];
FS.createStandardStreams();
},
quit: () => {
FS.init.initialized = false;
for (var i = 0; i < FS.streams.length; i++) {
var stream = FS.streams[i];
if (!stream) {
continue;
}
FS.close(stream);
}
},
getMode: (canRead, canWrite) => {
var mode = 0;
if (canRead) mode |= 292 | 73;
if (canWrite) mode |= 146;
return mode;
},
findObject: (path, dontResolveLastLink) => {
var ret = FS.analyzePath(path, dontResolveLastLink);
if (ret.exists) {
return ret.object;
} else {
return null;
}
},
analyzePath: (path, dontResolveLastLink) => {
try {
var lookup = FS.lookupPath(path, {
follow: !dontResolveLastLink
});
path = lookup.path;
} catch (e) {}
var ret = {
isRoot: false,
exists: false,
error: 0,
name: null,
path: null,
object: null,
parentExists: false,
parentPath: null,
parentObject: null
};
try {
var lookup = FS.lookupPath(path, {
parent: true
});
ret.parentExists = true;
ret.parentPath = lookup.path;
ret.parentObject = lookup.node;
ret.name = PATH.basename(path);
lookup = FS.lookupPath(path, {
follow: !dontResolveLastLink
});
ret.exists = true;
ret.path = lookup.path;
ret.object = lookup.node;
ret.name = lookup.node.name;
ret.isRoot = lookup.path === "/";
} catch (e) {
ret.error = e.errno;
}
return ret;
},
createPath: (parent, path, canRead, canWrite) => {
parent = typeof parent == "string" ? parent : FS.getPath(parent);
var parts = path.split("/").reverse();
while (parts.length) {
var part = parts.pop();
if (!part) continue;
var current = PATH.join2(parent, part);
try {
FS.mkdir(current);
} catch (e) {}
parent = current;
}
return current;
},
createFile: (parent, name, properties, canRead, canWrite) => {
var path = PATH.join2(typeof parent == "string" ? parent : FS.getPath(parent), name);
var mode = FS.getMode(canRead, canWrite);
return FS.create(path, mode);
},
createDataFile: (parent, name, data, canRead, canWrite, canOwn) => {
var path = name;
if (parent) {
parent = typeof parent == "string" ? parent : FS.getPath(parent);
path = name ? PATH.join2(parent, name) : parent;
}
var mode = FS.getMode(canRead, canWrite);
var node = FS.create(path, mode);
if (data) {
if (typeof data == "string") {
var arr = new Array(data.length);
for (var i = 0, len = data.length; i < len; ++i) arr[i] = data.charCodeAt(i);
data = arr;
}
FS.chmod(node, mode | 146);
var stream = FS.open(node, 577);
FS.write(stream, data, 0, data.length, 0, canOwn);
FS.close(stream);
FS.chmod(node, mode);
}
return node;
},
createDevice: (parent, name, input, output) => {
var path = PATH.join2(typeof parent == "string" ? parent : FS.getPath(parent), name);
var mode = FS.getMode(!!input, !!output);
if (!FS.createDevice.major) FS.createDevice.major = 64;
var dev = FS.makedev(FS.createDevice.major++, 0);
FS.registerDevice(dev, {
open: stream => {
stream.seekable = false;
},
close: stream => {
if (output && output.buffer && output.buffer.length) {
output(10);
}
},
read: (stream, buffer, offset, length, pos) => {
var bytesRead = 0;
for (var i = 0; i < length; i++) {
var result;
try {
result = input();
} catch (e) {
throw new FS.ErrnoError(29);
}
if (result === undefined && bytesRead === 0) {
throw new FS.ErrnoError(6);
}
if (result === null || result === undefined) break;
bytesRead++;
buffer[offset + i] = result;
}
if (bytesRead) {
stream.node.timestamp = Date.now();
}
return bytesRead;
},
write: (stream, buffer, offset, length, pos) => {
for (var i = 0; i < length; i++) {
try {
output(buffer[offset + i]);
} catch (e) {
throw new FS.ErrnoError(29);
}
}
if (length) {
stream.node.timestamp = Date.now();
}
return i;
}
});
return FS.mkdev(path, mode, dev);
},
forceLoadFile: obj => {
if (obj.isDevice || obj.isFolder || obj.link || obj.contents) return true;
if (typeof XMLHttpRequest != "undefined") {
throw new Error("Lazy loading should have been performed (contents set) in createLazyFile, but it was not. Lazy loading only works in web workers. Use --embed-file or --preload-file in emcc on the main thread.");
} else if (read_) {
try {
obj.contents = intArrayFromString(read_(obj.url), true);
obj.usedBytes = obj.contents.length;
} catch (e) {
throw new FS.ErrnoError(29);
}
} else {
throw new Error("Cannot load without read() or XMLHttpRequest.");
}
},
createLazyFile: (parent, name, url, canRead, canWrite) => {
function LazyUint8Array() {
this.lengthKnown = false;
this.chunks = [];
}
LazyUint8Array.prototype.get = function LazyUint8Array_get(idx) {
if (idx > this.length - 1 || idx < 0) {
return undefined;
}
var chunkOffset = idx % this.chunkSize;
var chunkNum = idx / this.chunkSize | 0;
return this.getter(chunkNum)[chunkOffset];
};
LazyUint8Array.prototype.setDataGetter = function LazyUint8Array_setDataGetter(getter) {
this.getter = getter;
};
LazyUint8Array.prototype.cacheLength = function LazyUint8Array_cacheLength() {
var xhr = new XMLHttpRequest();
xhr.open("HEAD", url, false);
xhr.send(null);
if (!(xhr.status >= 200 && xhr.status < 300 || xhr.status === 304)) throw new Error("Couldn't load " + url + ". Status: " + xhr.status);
var datalength = Number(xhr.getResponseHeader("Content-length"));
var header;
var hasByteServing = (header = xhr.getResponseHeader("Accept-Ranges")) && header === "bytes";
var usesGzip = (header = xhr.getResponseHeader("Content-Encoding")) && header === "gzip";
var chunkSize = 1024 * 1024;
if (!hasByteServing) chunkSize = datalength;
var doXHR = (from, to) => {
if (from > to) throw new Error("invalid range (" + from + ", " + to + ") or no bytes requested!");
if (to > datalength - 1) throw new Error("only " + datalength + " bytes available! programmer error!");
var xhr = new XMLHttpRequest();
xhr.open("GET", url, false);
if (datalength !== chunkSize) xhr.setRequestHeader("Range", "bytes=" + from + "-" + to);
xhr.responseType = "arraybuffer";
if (xhr.overrideMimeType) {
xhr.overrideMimeType("text/plain; charset=x-user-defined");
}
xhr.send(null);
if (!(xhr.status >= 200 && xhr.status < 300 || xhr.status === 304)) throw new Error("Couldn't load " + url + ". Status: " + xhr.status);
if (xhr.response !== undefined) {
return new Uint8Array(xhr.response || []);
} else {
return intArrayFromString(xhr.responseText || "", true);
}
};
var lazyArray = this;
lazyArray.setDataGetter(chunkNum => {
var start = chunkNum * chunkSize;
var end = (chunkNum + 1) * chunkSize - 1;
end = Math.min(end, datalength - 1);
if (typeof lazyArray.chunks[chunkNum] == "undefined") {
lazyArray.chunks[chunkNum] = doXHR(start, end);
}
if (typeof lazyArray.chunks[chunkNum] == "undefined") throw new Error("doXHR failed!");
return lazyArray.chunks[chunkNum];
});
if (usesGzip || !datalength) {
chunkSize = datalength = 1;
datalength = this.getter(0).length;
chunkSize = datalength;
out("LazyFiles on gzip forces download of the whole file when length is accessed");
}
this._length = datalength;
this._chunkSize = chunkSize;
this.lengthKnown = true;
};
if (typeof XMLHttpRequest != "undefined") {
if (!ENVIRONMENT_IS_WORKER) throw "Cannot do synchronous binary XHRs outside webworkers in modern browsers. Use --embed-file or --preload-file in emcc";
var lazyArray = new LazyUint8Array();
Object.defineProperties(lazyArray, {
length: {
get: function() {
if (!this.lengthKnown) {
this.cacheLength();
}
return this._length;
}
},
chunkSize: {
get: function() {
if (!this.lengthKnown) {
this.cacheLength();
}
return this._chunkSize;
}
}
});
var properties = {
isDevice: false,
contents: lazyArray
};
} else {
var properties = {
isDevice: false,
url: url
};
}
var node = FS.createFile(parent, name, properties, canRead, canWrite);
if (properties.contents) {
node.contents = properties.contents;
} else if (properties.url) {
node.contents = null;
node.url = properties.url;
}
Object.defineProperties(node, {
usedBytes: {
get: function() {
return this.contents.length;
}
}
});
var stream_ops = {};
var keys = Object.keys(node.stream_ops);
keys.forEach(key => {
var fn = node.stream_ops[key];
stream_ops[key] = function forceLoadLazyFile() {
FS.forceLoadFile(node);
return fn.apply(null, arguments);
};
});
stream_ops.read = (stream, buffer, offset, length, position) => {
FS.forceLoadFile(node);
var contents = stream.node.contents;
if (position >= contents.length) return 0;
var size = Math.min(contents.length - position, length);
if (contents.slice) {
for (var i = 0; i < size; i++) {
buffer[offset + i] = contents[position + i];
}
} else {
for (var i = 0; i < size; i++) {
buffer[offset + i] = contents.get(position + i);
}
}
return size;
};
node.stream_ops = stream_ops;
return node;
},
createPreloadedFile: (parent, name, url, canRead, canWrite, onload, onerror, dontCreateFile, canOwn, preFinish) => {
var fullname = name ? PATH_FS.resolve(PATH.join2(parent, name)) : parent;
var dep = getUniqueRunDependency("cp " + fullname);
function processData(byteArray) {
function finish(byteArray) {
if (preFinish) preFinish();
if (!dontCreateFile) {
FS.createDataFile(parent, name, byteArray, canRead, canWrite, canOwn);
}
if (onload) onload();
removeRunDependency(dep);
}
if (Browser.handledByPreloadPlugin(byteArray, fullname, finish, () => {
if (onerror) onerror();
removeRunDependency(dep);
})) {
return;
}
finish(byteArray);
}
addRunDependency(dep);
if (typeof url == "string") {
asyncLoad(url, byteArray => processData(byteArray), onerror);
} else {
processData(url);
}
},
indexedDB: () => {
return window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB;
},
DB_NAME: () => {
return "EM_FS_" + window.location.pathname;
},
DB_VERSION: 20,
DB_STORE_NAME: "FILE_DATA",
saveFilesToDB: (paths, onload, onerror) => {
onload = onload || (() => {});
onerror = onerror || (() => {});
var indexedDB = FS.indexedDB();
try {
var openRequest = indexedDB.open(FS.DB_NAME(), FS.DB_VERSION);
} catch (e) {
return onerror(e);
}
openRequest.onupgradeneeded = () => {
out("creating db");
var db = openRequest.result;
db.createObjectStore(FS.DB_STORE_NAME);
};
openRequest.onsuccess = () => {
var db = openRequest.result;
var transaction = db.transaction([ FS.DB_STORE_NAME ], "readwrite");
var files = transaction.objectStore(FS.DB_STORE_NAME);
var ok = 0, fail = 0, total = paths.length;
function finish() {
if (fail == 0) onload(); else onerror();
}
paths.forEach(path => {
var putRequest = files.put(FS.analyzePath(path).object.contents, path);
putRequest.onsuccess = () => {
ok++;
if (ok + fail == total) finish();
};
putRequest.onerror = () => {
fail++;
if (ok + fail == total) finish();
};
});
transaction.onerror = onerror;
};
openRequest.onerror = onerror;
},
loadFilesFromDB: (paths, onload, onerror) => {
onload = onload || (() => {});
onerror = onerror || (() => {});
var indexedDB = FS.indexedDB();
try {
var openRequest = indexedDB.open(FS.DB_NAME(), FS.DB_VERSION);
} catch (e) {
return onerror(e);
}
openRequest.onupgradeneeded = onerror;
openRequest.onsuccess = () => {
var db = openRequest.result;
try {
var transaction = db.transaction([ FS.DB_STORE_NAME ], "readonly");
} catch (e) {
onerror(e);
return;
}
var files = transaction.objectStore(FS.DB_STORE_NAME);
var ok = 0, fail = 0, total = paths.length;
function finish() {
if (fail == 0) onload(); else onerror();
}
paths.forEach(path => {
var getRequest = files.get(path);
getRequest.onsuccess = () => {
if (FS.analyzePath(path).exists) {
FS.unlink(path);
}
FS.createDataFile(PATH.dirname(path), PATH.basename(path), getRequest.result, true, true, true);
ok++;
if (ok + fail == total) finish();
};
getRequest.onerror = () => {
fail++;
if (ok + fail == total) finish();
};
});
transaction.onerror = onerror;
};
openRequest.onerror = onerror;
}
};
var SYSCALLS = {
DEFAULT_POLLMASK: 5,
calculateAt: function(dirfd, path, allowEmpty) {
if (PATH.isAbs(path)) {
return path;
}
var dir;
if (dirfd === -100) {
dir = FS.cwd();
} else {
var dirstream = FS.getStream(dirfd);
if (!dirstream) throw new FS.ErrnoError(8);
dir = dirstream.path;
}
if (path.length == 0) {
if (!allowEmpty) {
throw new FS.ErrnoError(44);
}
return dir;
}
return PATH.join2(dir, path);
},
doStat: function(func, path, buf) {
try {
var stat = func(path);
} catch (e) {
if (e && e.node && PATH.normalize(path) !== PATH.normalize(FS.getPath(e.node))) {
return -54;
}
throw e;
}
GROWABLE_HEAP_I32()[buf >> 2] = stat.dev;
GROWABLE_HEAP_I32()[buf + 4 >> 2] = 0;
GROWABLE_HEAP_I32()[buf + 8 >> 2] = stat.ino;
GROWABLE_HEAP_I32()[buf + 12 >> 2] = stat.mode;
GROWABLE_HEAP_I32()[buf + 16 >> 2] = stat.nlink;
GROWABLE_HEAP_I32()[buf + 20 >> 2] = stat.uid;
GROWABLE_HEAP_I32()[buf + 24 >> 2] = stat.gid;
GROWABLE_HEAP_I32()[buf + 28 >> 2] = stat.rdev;
GROWABLE_HEAP_I32()[buf + 32 >> 2] = 0;
tempI64 = [ stat.size >>> 0, (tempDouble = stat.size, +Math.abs(tempDouble) >= 1 ? tempDouble > 0 ? (Math.min(+Math.floor(tempDouble / 4294967296), 4294967295) | 0) >>> 0 : ~~+Math.ceil((tempDouble - +(~~tempDouble >>> 0)) / 4294967296) >>> 0 : 0) ],
GROWABLE_HEAP_I32()[buf + 40 >> 2] = tempI64[0], GROWABLE_HEAP_I32()[buf + 44 >> 2] = tempI64[1];
GROWABLE_HEAP_I32()[buf + 48 >> 2] = 4096;
GROWABLE_HEAP_I32()[buf + 52 >> 2] = stat.blocks;
GROWABLE_HEAP_I32()[buf + 56 >> 2] = stat.atime.getTime() / 1e3 | 0;
GROWABLE_HEAP_I32()[buf + 60 >> 2] = 0;
GROWABLE_HEAP_I32()[buf + 64 >> 2] = stat.mtime.getTime() / 1e3 | 0;
GROWABLE_HEAP_I32()[buf + 68 >> 2] = 0;
GROWABLE_HEAP_I32()[buf + 72 >> 2] = stat.ctime.getTime() / 1e3 | 0;
GROWABLE_HEAP_I32()[buf + 76 >> 2] = 0;
tempI64 = [ stat.ino >>> 0, (tempDouble = stat.ino, +Math.abs(tempDouble) >= 1 ? tempDouble > 0 ? (Math.min(+Math.floor(tempDouble / 4294967296), 4294967295) | 0) >>> 0 : ~~+Math.ceil((tempDouble - +(~~tempDouble >>> 0)) / 4294967296) >>> 0 : 0) ],
GROWABLE_HEAP_I32()[buf + 80 >> 2] = tempI64[0], GROWABLE_HEAP_I32()[buf + 84 >> 2] = tempI64[1];
return 0;
},
doMsync: function(addr, stream, len, flags, offset) {
var buffer = GROWABLE_HEAP_U8().slice(addr, addr + len);
FS.msync(stream, buffer, offset, len, flags);
},
varargs: undefined,
get: function() {
SYSCALLS.varargs += 4;
var ret = GROWABLE_HEAP_I32()[SYSCALLS.varargs - 4 >> 2];
return ret;
},
getStr: function(ptr) {
var ret = UTF8ToString(ptr);
return ret;
},
getStreamFromFD: function(fd) {
var stream = FS.getStream(fd);
if (!stream) throw new FS.ErrnoError(8);
return stream;
}
};
function ___syscall__newselect(nfds, readfds, writefds, exceptfds, timeout) {
if (ENVIRONMENT_IS_PTHREAD) return _emscripten_proxy_to_main_thread_js(3, 1, nfds, readfds, writefds, exceptfds, timeout);
try {
var total = 0;
var srcReadLow = readfds ? GROWABLE_HEAP_I32()[readfds >> 2] : 0, srcReadHigh = readfds ? GROWABLE_HEAP_I32()[readfds + 4 >> 2] : 0;
var srcWriteLow = writefds ? GROWABLE_HEAP_I32()[writefds >> 2] : 0, srcWriteHigh = writefds ? GROWABLE_HEAP_I32()[writefds + 4 >> 2] : 0;
var srcExceptLow = exceptfds ? GROWABLE_HEAP_I32()[exceptfds >> 2] : 0, srcExceptHigh = exceptfds ? GROWABLE_HEAP_I32()[exceptfds + 4 >> 2] : 0;
var dstReadLow = 0, dstReadHigh = 0;
var dstWriteLow = 0, dstWriteHigh = 0;
var dstExceptLow = 0, dstExceptHigh = 0;
var allLow = (readfds ? GROWABLE_HEAP_I32()[readfds >> 2] : 0) | (writefds ? GROWABLE_HEAP_I32()[writefds >> 2] : 0) | (exceptfds ? GROWABLE_HEAP_I32()[exceptfds >> 2] : 0);
var allHigh = (readfds ? GROWABLE_HEAP_I32()[readfds + 4 >> 2] : 0) | (writefds ? GROWABLE_HEAP_I32()[writefds + 4 >> 2] : 0) | (exceptfds ? GROWABLE_HEAP_I32()[exceptfds + 4 >> 2] : 0);
var check = function(fd, low, high, val) {
return fd < 32 ? low & val : high & val;
};
for (var fd = 0; fd < nfds; fd++) {
var mask = 1 << fd % 32;
if (!check(fd, allLow, allHigh, mask)) {
continue;
}
var stream = FS.getStream(fd);
if (!stream) throw new FS.ErrnoError(8);
var flags = SYSCALLS.DEFAULT_POLLMASK;
if (stream.stream_ops.poll) {
flags = stream.stream_ops.poll(stream);
}
if (flags & 1 && check(fd, srcReadLow, srcReadHigh, mask)) {
fd < 32 ? dstReadLow = dstReadLow | mask : dstReadHigh = dstReadHigh | mask;
total++;
}
if (flags & 4 && check(fd, srcWriteLow, srcWriteHigh, mask)) {
fd < 32 ? dstWriteLow = dstWriteLow | mask : dstWriteHigh = dstWriteHigh | mask;
total++;
}
if (flags & 2 && check(fd, srcExceptLow, srcExceptHigh, mask)) {
fd < 32 ? dstExceptLow = dstExceptLow | mask : dstExceptHigh = dstExceptHigh | mask;
total++;
}
}
if (readfds) {
GROWABLE_HEAP_I32()[readfds >> 2] = dstReadLow;
GROWABLE_HEAP_I32()[readfds + 4 >> 2] = dstReadHigh;
}
if (writefds) {
GROWABLE_HEAP_I32()[writefds >> 2] = dstWriteLow;
GROWABLE_HEAP_I32()[writefds + 4 >> 2] = dstWriteHigh;
}
if (exceptfds) {
GROWABLE_HEAP_I32()[exceptfds >> 2] = dstExceptLow;
GROWABLE_HEAP_I32()[exceptfds + 4 >> 2] = dstExceptHigh;
}
return total;
} catch (e) {
if (typeof FS == "undefined" || !(e instanceof FS.ErrnoError)) throw e;
return -e.errno;
}
}
var SOCKFS = {
mount: function(mount) {
Module["websocket"] = Module["websocket"] && "object" === typeof Module["websocket"] ? Module["websocket"] : {};
Module["websocket"]._callbacks = {};
Module["websocket"]["on"] = function(event, callback) {
if ("function" === typeof callback) {
this._callbacks[event] = callback;
}
return this;
};
Module["websocket"].emit = function(event, param) {
if ("function" === typeof this._callbacks[event]) {
this._callbacks[event].call(this, param);
}
};
return FS.createNode(null, "/", 16384 | 511, 0);
},
createSocket: function(family, type, protocol) {
type &= ~526336;
var streaming = type == 1;
if (streaming && protocol && protocol != 6) {
throw new FS.ErrnoError(66);
}
var sock = {
family: family,
type: type,
protocol: protocol,
server: null,
error: null,
peers: {},
pending: [],
recv_queue: [],
sock_ops: SOCKFS.websocket_sock_ops
};
var name = SOCKFS.nextname();
var node = FS.createNode(SOCKFS.root, name, 49152, 0);
node.sock = sock;
var stream = FS.createStream({
path: name,
node: node,
flags: 2,
seekable: false,
stream_ops: SOCKFS.stream_ops
});
sock.stream = stream;
return sock;
},
getSocket: function(fd) {
var stream = FS.getStream(fd);
if (!stream || !FS.isSocket(stream.node.mode)) {
return null;
}
return stream.node.sock;
},
stream_ops: {
poll: function(stream) {
var sock = stream.node.sock;
return sock.sock_ops.poll(sock);
},
ioctl: function(stream, request, varargs) {
var sock = stream.node.sock;
return sock.sock_ops.ioctl(sock, request, varargs);
},
read: function(stream, buffer, offset, length, position) {
var sock = stream.node.sock;
var msg = sock.sock_ops.recvmsg(sock, length);
if (!msg) {
return 0;
}
buffer.set(msg.buffer, offset);
return msg.buffer.length;
},
write: function(stream, buffer, offset, length, position) {
var sock = stream.node.sock;
return sock.sock_ops.sendmsg(sock, buffer, offset, length);
},
close: function(stream) {
var sock = stream.node.sock;
sock.sock_ops.close(sock);
}
},
nextname: function() {
if (!SOCKFS.nextname.current) {
SOCKFS.nextname.current = 0;
}
return "socket[" + SOCKFS.nextname.current++ + "]";
},
websocket_sock_ops: {
createPeer: function(sock, addr, port) {
var ws;
if (typeof addr == "object") {
ws = addr;
addr = null;
port = null;
}
if (ws) {
if (ws._socket) {
addr = ws._socket.remoteAddress;
port = ws._socket.remotePort;
} else {
var result = /ws[s]?:\/\/([^:]+):(\d+)/.exec(ws.url);
if (!result) {
throw new Error("WebSocket URL must be in the format ws(s)://address:port");
}
addr = result[1];
port = parseInt(result[2], 10);
}
} else {
try {
var runtimeConfig = Module["websocket"] && "object" === typeof Module["websocket"];
var url = "ws:#".replace("#", "//");
if (runtimeConfig) {
if ("string" === typeof Module["websocket"]["url"]) {
url = Module["websocket"]["url"];
}
}
if (url === "ws://" || url === "wss://") {
var parts = addr.split("/");
url = url + parts[0] + ":" + port + "/" + parts.slice(1).join("/");
}
var subProtocols = "binary";
if (runtimeConfig) {
if ("string" === typeof Module["websocket"]["subprotocol"]) {
subProtocols = Module["websocket"]["subprotocol"];
}
}
var opts = undefined;
if (subProtocols !== "null") {
subProtocols = subProtocols.replace(/^ +| +$/g, "").split(/ *, */);
opts = subProtocols;
}
if (runtimeConfig && null === Module["websocket"]["subprotocol"]) {
subProtocols = "null";
opts = undefined;
}
var WebSocketConstructor;
if (ENVIRONMENT_IS_NODE) {
WebSocketConstructor = require("ws");
} else {
WebSocketConstructor = WebSocket;
}
ws = new WebSocketConstructor(url, opts);
ws.binaryType = "arraybuffer";
} catch (e) {
throw new FS.ErrnoError(23);
}
}
var peer = {
addr: addr,
port: port,
socket: ws,
dgram_send_queue: []
};
SOCKFS.websocket_sock_ops.addPeer(sock, peer);
SOCKFS.websocket_sock_ops.handlePeerEvents(sock, peer);
if (sock.type === 2 && typeof sock.sport != "undefined") {
peer.dgram_send_queue.push(new Uint8Array([ 255, 255, 255, 255, "p".charCodeAt(0), "o".charCodeAt(0), "r".charCodeAt(0), "t".charCodeAt(0), (sock.sport & 65280) >> 8, sock.sport & 255 ]));
}
return peer;
},
getPeer: function(sock, addr, port) {
return sock.peers[addr + ":" + port];
},
addPeer: function(sock, peer) {
sock.peers[peer.addr + ":" + peer.port] = peer;
},
removePeer: function(sock, peer) {
delete sock.peers[peer.addr + ":" + peer.port];
},
handlePeerEvents: function(sock, peer) {
var first = true;
var handleOpen = function() {
Module["websocket"].emit("open", sock.stream.fd);
try {
var queued = peer.dgram_send_queue.shift();
while (queued) {
peer.socket.send(queued);
queued = peer.dgram_send_queue.shift();
}
} catch (e) {
peer.socket.close();
}
};
function handleMessage(data) {
if (typeof data == "string") {
var encoder = new TextEncoder();
data = encoder.encode(data);
} else {
assert(data.byteLength !== undefined);
if (data.byteLength == 0) {
return;
} else {
data = new Uint8Array(data);
}
}
var wasfirst = first;
first = false;
if (wasfirst && data.length === 10 && data[0] === 255 && data[1] === 255 && data[2] === 255 && data[3] === 255 && data[4] === "p".charCodeAt(0) && data[5] === "o".charCodeAt(0) && data[6] === "r".charCodeAt(0) && data[7] === "t".charCodeAt(0)) {
var newport = data[8] << 8 | data[9];
SOCKFS.websocket_sock_ops.removePeer(sock, peer);
peer.port = newport;
SOCKFS.websocket_sock_ops.addPeer(sock, peer);
return;
}
sock.recv_queue.push({
addr: peer.addr,
port: peer.port,
data: data
});
Module["websocket"].emit("message", sock.stream.fd);
}
if (ENVIRONMENT_IS_NODE) {
peer.socket.on("open", handleOpen);
peer.socket.on("message", function(data, isBinary) {
if (!isBinary) {
return;
}
handleMessage(new Uint8Array(data).buffer);
});
peer.socket.on("close", function() {
Module["websocket"].emit("close", sock.stream.fd);
});
peer.socket.on("error", function(error) {
sock.error = 14;
Module["websocket"].emit("error", [ sock.stream.fd, sock.error, "ECONNREFUSED: Connection refused" ]);
});
} else {
peer.socket.onopen = handleOpen;
peer.socket.onclose = function() {
Module["websocket"].emit("close", sock.stream.fd);
};
peer.socket.onmessage = function peer_socket_onmessage(event) {
handleMessage(event.data);
};
peer.socket.onerror = function(error) {
sock.error = 14;
Module["websocket"].emit("error", [ sock.stream.fd, sock.error, "ECONNREFUSED: Connection refused" ]);
};
}
},
poll: function(sock) {
if (sock.type === 1 && sock.server) {
return sock.pending.length ? 64 | 1 : 0;
}
var mask = 0;
var dest = sock.type === 1 ? SOCKFS.websocket_sock_ops.getPeer(sock, sock.daddr, sock.dport) : null;
if (sock.recv_queue.length || !dest || dest && dest.socket.readyState === dest.socket.CLOSING || dest && dest.socket.readyState === dest.socket.CLOSED) {
mask |= 64 | 1;
}
if (!dest || dest && dest.socket.readyState === dest.socket.OPEN) {
mask |= 4;
}
if (dest && dest.socket.readyState === dest.socket.CLOSING || dest && dest.socket.readyState === dest.socket.CLOSED) {
mask |= 16;
}
return mask;
},
ioctl: function(sock, request, arg) {
switch (request) {
case 21531:
var bytes = 0;
if (sock.recv_queue.length) {
bytes = sock.recv_queue[0].data.length;
}
GROWABLE_HEAP_I32()[arg >> 2] = bytes;
return 0;
default:
return 28;
}
},
close: function(sock) {
if (sock.server) {
try {
sock.server.close();
} catch (e) {}
sock.server = null;
}
var peers = Object.keys(sock.peers);
for (var i = 0; i < peers.length; i++) {
var peer = sock.peers[peers[i]];
try {
peer.socket.close();
} catch (e) {}
SOCKFS.websocket_sock_ops.removePeer(sock, peer);
}
return 0;
},
bind: function(sock, addr, port) {
if (typeof sock.saddr != "undefined" || typeof sock.sport != "undefined") {
throw new FS.ErrnoError(28);
}
sock.saddr = addr;
sock.sport = port;
if (sock.type === 2) {
if (sock.server) {
sock.server.close();
sock.server = null;
}
try {
sock.sock_ops.listen(sock, 0);
} catch (e) {
if (!(e instanceof FS.ErrnoError)) throw e;
if (e.errno !== 138) throw e;
}
}
},
connect: function(sock, addr, port) {
if (sock.server) {
throw new FS.ErrnoError(138);
}
if (typeof sock.daddr != "undefined" && typeof sock.dport != "undefined") {
var dest = SOCKFS.websocket_sock_ops.getPeer(sock, sock.daddr, sock.dport);
if (dest) {
if (dest.socket.readyState === dest.socket.CONNECTING) {
throw new FS.ErrnoError(7);
} else {
throw new FS.ErrnoError(30);
}
}
}
var peer = SOCKFS.websocket_sock_ops.createPeer(sock, addr, port);
sock.daddr = peer.addr;
sock.dport = peer.port;
throw new FS.ErrnoError(26);
},
listen: function(sock, backlog) {
if (!ENVIRONMENT_IS_NODE) {
throw new FS.ErrnoError(138);
}
if (sock.server) {
throw new FS.ErrnoError(28);
}
var WebSocketServer = require("ws").Server;
var host = sock.saddr;
sock.server = new WebSocketServer({
host: host,
port: sock.sport
});
Module["websocket"].emit("listen", sock.stream.fd);
sock.server.on("connection", function(ws) {
if (sock.type === 1) {
var newsock = SOCKFS.createSocket(sock.family, sock.type, sock.protocol);
var peer = SOCKFS.websocket_sock_ops.createPeer(newsock, ws);
newsock.daddr = peer.addr;
newsock.dport = peer.port;
sock.pending.push(newsock);
Module["websocket"].emit("connection", newsock.stream.fd);
} else {
SOCKFS.websocket_sock_ops.createPeer(sock, ws);
Module["websocket"].emit("connection", sock.stream.fd);
}
});
sock.server.on("close", function() {
Module["websocket"].emit("close", sock.stream.fd);
sock.server = null;
});
sock.server.on("error", function(error) {
sock.error = 23;
Module["websocket"].emit("error", [ sock.stream.fd, sock.error, "EHOSTUNREACH: Host is unreachable" ]);
});
},
accept: function(listensock) {
if (!listensock.server || !listensock.pending.length) {
throw new FS.ErrnoError(28);
}
var newsock = listensock.pending.shift();
newsock.stream.flags = listensock.stream.flags;
return newsock;
},
getname: function(sock, peer) {
var addr, port;
if (peer) {
if (sock.daddr === undefined || sock.dport === undefined) {
throw new FS.ErrnoError(53);
}
addr = sock.daddr;
port = sock.dport;
} else {
addr = sock.saddr || 0;
port = sock.sport || 0;
}
return {
addr: addr,
port: port
};
},
sendmsg: function(sock, buffer, offset, length, addr, port) {
if (sock.type === 2) {
if (addr === undefined || port === undefined) {
addr = sock.daddr;
port = sock.dport;
}
if (addr === undefined || port === undefined) {
throw new FS.ErrnoError(17);
}
} else {
addr = sock.daddr;
port = sock.dport;
}
var dest = SOCKFS.websocket_sock_ops.getPeer(sock, addr, port);
if (sock.type === 1) {
if (!dest || dest.socket.readyState === dest.socket.CLOSING || dest.socket.readyState === dest.socket.CLOSED) {
throw new FS.ErrnoError(53);
} else if (dest.socket.readyState === dest.socket.CONNECTING) {
throw new FS.ErrnoError(6);
}
}
if (ArrayBuffer.isView(buffer)) {
offset += buffer.byteOffset;
buffer = buffer.buffer;
}
var data;
if (buffer instanceof SharedArrayBuffer) {
data = new Uint8Array(new Uint8Array(buffer.slice(offset, offset + length))).buffer;
} else {
data = buffer.slice(offset, offset + length);
}
if (sock.type === 2) {
if (!dest || dest.socket.readyState !== dest.socket.OPEN) {
if (!dest || dest.socket.readyState === dest.socket.CLOSING || dest.socket.readyState === dest.socket.CLOSED) {
dest = SOCKFS.websocket_sock_ops.createPeer(sock, addr, port);
}
dest.dgram_send_queue.push(data);
return length;
}
}
try {
dest.socket.send(data);
return length;
} catch (e) {
throw new FS.ErrnoError(28);
}
},
recvmsg: function(sock, length) {
if (sock.type === 1 && sock.server) {
throw new FS.ErrnoError(53);
}
var queued = sock.recv_queue.shift();
if (!queued) {
if (sock.type === 1) {
var dest = SOCKFS.websocket_sock_ops.getPeer(sock, sock.daddr, sock.dport);
if (!dest) {
throw new FS.ErrnoError(53);
} else if (dest.socket.readyState === dest.socket.CLOSING || dest.socket.readyState === dest.socket.CLOSED) {
return null;
} else {
throw new FS.ErrnoError(6);
}
} else {
throw new FS.ErrnoError(6);
}
}
var queuedLength = queued.data.byteLength || queued.data.length;
var queuedOffset = queued.data.byteOffset || 0;
var queuedBuffer = queued.data.buffer || queued.data;
var bytesRead = Math.min(length, queuedLength);
var res = {
buffer: new Uint8Array(queuedBuffer, queuedOffset, bytesRead),
addr: queued.addr,
port: queued.port
};
if (sock.type === 1 && bytesRead < queuedLength) {
var bytesRemaining = queuedLength - bytesRead;
queued.data = new Uint8Array(queuedBuffer, queuedOffset + bytesRead, bytesRemaining);
sock.recv_queue.unshift(queued);
}
return res;
}
}
};
function getSocketFromFD(fd) {
var socket = SOCKFS.getSocket(fd);
if (!socket) throw new FS.ErrnoError(8);
return socket;
}
function setErrNo(value) {
GROWABLE_HEAP_I32()[___errno_location() >> 2] = value;
return value;
}
var Sockets = {
BUFFER_SIZE: 10240,
MAX_BUFFER_SIZE: 10485760,
nextFd: 1,
fds: {},
nextport: 1,
maxport: 65535,
peer: null,
connections: {},
portmap: {},
localAddr: 4261412874,
addrPool: [ 33554442, 50331658, 67108874, 83886090, 100663306, 117440522, 134217738, 150994954, 167772170, 184549386, 201326602, 218103818, 234881034 ]
};
function inetPton4(str) {
var b = str.split(".");
for (var i = 0; i < 4; i++) {
var tmp = Number(b[i]);
if (isNaN(tmp)) return null;
b[i] = tmp;
}
return (b[0] | b[1] << 8 | b[2] << 16 | b[3] << 24) >>> 0;
}
function jstoi_q(str) {
return parseInt(str);
}
function inetPton6(str) {
var words;
var w, offset, z, i;
var valid6regx = /^((?=.*::)(?!.*::.+::)(::)?([\dA-F]{1,4}:(:|\b)|){5}|([\dA-F]{1,4}:){6})((([\dA-F]{1,4}((?!\3)::|:\b|$))|(?!\2\3)){2}|(((2[0-4]|1\d|[1-9])?\d|25[0-5])\.?\b){4})$/i;
var parts = [];
if (!valid6regx.test(str)) {
return null;
}
if (str === "::") {
return [ 0, 0, 0, 0, 0, 0, 0, 0 ];
}
if (str.startsWith("::")) {
str = str.replace("::", "Z:");
} else {
str = str.replace("::", ":Z:");
}
if (str.indexOf(".") > 0) {
str = str.replace(new RegExp("[.]", "g"), ":");
words = str.split(":");
words[words.length - 4] = jstoi_q(words[words.length - 4]) + jstoi_q(words[words.length - 3]) * 256;
words[words.length - 3] = jstoi_q(words[words.length - 2]) + jstoi_q(words[words.length - 1]) * 256;
words = words.slice(0, words.length - 2);
} else {
words = str.split(":");
}
offset = 0;
z = 0;
for (w = 0; w < words.length; w++) {
if (typeof words[w] == "string") {
if (words[w] === "Z") {
for (z = 0; z < 8 - words.length + 1; z++) {
parts[w + z] = 0;
}
offset = z - 1;
} else {
parts[w + offset] = _htons(parseInt(words[w], 16));
}
} else {
parts[w + offset] = words[w];
}
}
return [ parts[1] << 16 | parts[0], parts[3] << 16 | parts[2], parts[5] << 16 | parts[4], parts[7] << 16 | parts[6] ];
}
function writeSockaddr(sa, family, addr, port, addrlen) {
switch (family) {
case 2:
addr = inetPton4(addr);
zeroMemory(sa, 16);
if (addrlen) {
GROWABLE_HEAP_I32()[addrlen >> 2] = 16;
}
GROWABLE_HEAP_I16()[sa >> 1] = family;
GROWABLE_HEAP_I32()[sa + 4 >> 2] = addr;
GROWABLE_HEAP_I16()[sa + 2 >> 1] = _htons(port);
break;
case 10:
addr = inetPton6(addr);
zeroMemory(sa, 28);
if (addrlen) {
GROWABLE_HEAP_I32()[addrlen >> 2] = 28;
}
GROWABLE_HEAP_I32()[sa >> 2] = family;
GROWABLE_HEAP_I32()[sa + 8 >> 2] = addr[0];
GROWABLE_HEAP_I32()[sa + 12 >> 2] = addr[1];
GROWABLE_HEAP_I32()[sa + 16 >> 2] = addr[2];
GROWABLE_HEAP_I32()[sa + 20 >> 2] = addr[3];
GROWABLE_HEAP_I16()[sa + 2 >> 1] = _htons(port);
break;
default:
return 5;
}
return 0;
}
var DNS = {
address_map: {
id: 1,
addrs: {},
names: {}
},
lookup_name: function(name) {
var res = inetPton4(name);
if (res !== null) {
return name;
}
res = inetPton6(name);
if (res !== null) {
return name;
}
var addr;
if (DNS.address_map.addrs[name]) {
addr = DNS.address_map.addrs[name];
} else {
var id = DNS.address_map.id++;
assert(id < 65535, "exceeded max address mappings of 65535");
addr = "172.29." + (id & 255) + "." + (id & 65280);
DNS.address_map.names[addr] = name;
DNS.address_map.addrs[name] = addr;
}
return addr;
},
lookup_addr: function(addr) {
if (DNS.address_map.names[addr]) {
return DNS.address_map.names[addr];
}
return null;
}
};
function ___syscall_accept4(fd, addr, addrlen, flags) {
if (ENVIRONMENT_IS_PTHREAD) return _emscripten_proxy_to_main_thread_js(4, 1, fd, addr, addrlen, flags);
try {
var sock = getSocketFromFD(fd);
var newsock = sock.sock_ops.accept(sock);
if (addr) {
var errno = writeSockaddr(addr, newsock.family, DNS.lookup_name(newsock.daddr), newsock.dport, addrlen);
}
return newsock.stream.fd;
} catch (e) {
if (typeof FS == "undefined" || !(e instanceof FS.ErrnoError)) throw e;
return -e.errno;
}
}
function inetNtop4(addr) {
return (addr & 255) + "." + (addr >> 8 & 255) + "." + (addr >> 16 & 255) + "." + (addr >> 24 & 255);
}
function inetNtop6(ints) {
var str = "";
var word = 0;
var longest = 0;
var lastzero = 0;
var zstart = 0;
var len = 0;
var i = 0;
var parts = [ ints[0] & 65535, ints[0] >> 16, ints[1] & 65535, ints[1] >> 16, ints[2] & 65535, ints[2] >> 16, ints[3] & 65535, ints[3] >> 16 ];
var hasipv4 = true;
var v4part = "";
for (i = 0; i < 5; i++) {
if (parts[i] !== 0) {
hasipv4 = false;
break;
}
}
if (hasipv4) {
v4part = inetNtop4(parts[6] | parts[7] << 16);
if (parts[5] === -1) {
str = "::ffff:";
str += v4part;
return str;
}
if (parts[5] === 0) {
str = "::";
if (v4part === "0.0.0.0") v4part = "";
if (v4part === "0.0.0.1") v4part = "1";
str += v4part;
return str;
}
}
for (word = 0; word < 8; word++) {
if (parts[word] === 0) {
if (word - lastzero > 1) {
len = 0;
}
lastzero = word;
len++;
}
if (len > longest) {
longest = len;
zstart = word - longest + 1;
}
}
for (word = 0; word < 8; word++) {
if (longest > 1) {
if (parts[word] === 0 && word >= zstart && word < zstart + longest) {
if (word === zstart) {
str += ":";
if (zstart === 0) str += ":";
}
continue;
}
}
str += Number(_ntohs(parts[word] & 65535)).toString(16);
str += word < 7 ? ":" : "";
}
return str;
}
function readSockaddr(sa, salen) {
var family = GROWABLE_HEAP_I16()[sa >> 1];
var port = _ntohs(GROWABLE_HEAP_U16()[sa + 2 >> 1]);
var addr;
switch (family) {
case 2:
if (salen !== 16) {
return {
errno: 28
};
}
addr = GROWABLE_HEAP_I32()[sa + 4 >> 2];
addr = inetNtop4(addr);
break;
case 10:
if (salen !== 28) {
return {
errno: 28
};
}
addr = [ GROWABLE_HEAP_I32()[sa + 8 >> 2], GROWABLE_HEAP_I32()[sa + 12 >> 2], GROWABLE_HEAP_I32()[sa + 16 >> 2], GROWABLE_HEAP_I32()[sa + 20 >> 2] ];
addr = inetNtop6(addr);
break;
default:
return {
errno: 5
};
}
return {
family: family,
addr: addr,
port: port
};
}
function getSocketAddress(addrp, addrlen, allowNull) {
if (allowNull && addrp === 0) return null;
var info = readSockaddr(addrp, addrlen);
if (info.errno) throw new FS.ErrnoError(info.errno);
info.addr = DNS.lookup_addr(info.addr) || info.addr;
return info;
}
function ___syscall_bind(fd, addr, addrlen) {
if (ENVIRONMENT_IS_PTHREAD) return _emscripten_proxy_to_main_thread_js(5, 1, fd, addr, addrlen);
try {
var sock = getSocketFromFD(fd);
var info = getSocketAddress(addr, addrlen);
sock.sock_ops.bind(sock, info.addr, info.port);
return 0;
} catch (e) {
if (typeof FS == "undefined" || !(e instanceof FS.ErrnoError)) throw e;
return -e.errno;
}
}
function ___syscall_chdir(path) {
if (ENVIRONMENT_IS_PTHREAD) return _emscripten_proxy_to_main_thread_js(6, 1, path);
try {
path = SYSCALLS.getStr(path);
FS.chdir(path);
return 0;
} catch (e) {
if (typeof FS == "undefined" || !(e instanceof FS.ErrnoError)) throw e;
return -e.errno;
}
}
function ___syscall_chmod(path, mode) {
if (ENVIRONMENT_IS_PTHREAD) return _emscripten_proxy_to_main_thread_js(7, 1, path, mode);
try {
path = SYSCALLS.getStr(path);
FS.chmod(path, mode);
return 0;
} catch (e) {
if (typeof FS == "undefined" || !(e instanceof FS.ErrnoError)) throw e;
return -e.errno;
}
}
function ___syscall_connect(fd, addr, addrlen) {
if (ENVIRONMENT_IS_PTHREAD) return _emscripten_proxy_to_main_thread_js(8, 1, fd, addr, addrlen);
try {
var sock = getSocketFromFD(fd);
var info = getSocketAddress(addr, addrlen);
sock.sock_ops.connect(sock, info.addr, info.port);
return 0;
} catch (e) {
if (typeof FS == "undefined" || !(e instanceof FS.ErrnoError)) throw e;
return -e.errno;
}
}
function ___syscall_faccessat(dirfd, path, amode, flags) {
if (ENVIRONMENT_IS_PTHREAD) return _emscripten_proxy_to_main_thread_js(9, 1, dirfd, path, amode, flags);
try {
path = SYSCALLS.getStr(path);
path = SYSCALLS.calculateAt(dirfd, path);
if (amode & ~7) {
return -28;
}
var lookup = FS.lookupPath(path, {
follow: true
});
var node = lookup.node;
if (!node) {
return -44;
}
var perms = "";
if (amode & 4) perms += "r";
if (amode & 2) perms += "w";
if (amode & 1) perms += "x";
if (perms && FS.nodePermissions(node, perms)) {
return -2;
}
return 0;
} catch (e) {
if (typeof FS == "undefined" || !(e instanceof FS.ErrnoError)) throw e;
return -e.errno;
}
}
function ___syscall_fadvise64(fd, offset, len, advice) {
return 0;
}
function ___syscall_fchmod(fd, mode) {
if (ENVIRONMENT_IS_PTHREAD) return _emscripten_proxy_to_main_thread_js(10, 1, fd, mode);
try {
FS.fchmod(fd, mode);
return 0;
} catch (e) {
if (typeof FS == "undefined" || !(e instanceof FS.ErrnoError)) throw e;
return -e.errno;
}
}
function ___syscall_fcntl64(fd, cmd, varargs) {
if (ENVIRONMENT_IS_PTHREAD) return _emscripten_proxy_to_main_thread_js(11, 1, fd, cmd, varargs);
SYSCALLS.varargs = varargs;
try {
var stream = SYSCALLS.getStreamFromFD(fd);
switch (cmd) {
case 0:
{
var arg = SYSCALLS.get();
if (arg < 0) {
return -28;
}
var newStream;
newStream = FS.createStream(stream, arg);
return newStream.fd;
}
case 1:
case 2:
return 0;
case 3:
return stream.flags;
case 4:
{
var arg = SYSCALLS.get();
stream.flags |= arg;
return 0;
}
case 5:
{
var arg = SYSCALLS.get();
var offset = 0;
GROWABLE_HEAP_I16()[arg + offset >> 1] = 2;
return 0;
}
case 6:
case 7:
return 0;
case 16:
case 8:
return -28;
case 9:
setErrNo(28);
return -1;
default:
{
return -28;
}
}
} catch (e) {
if (typeof FS == "undefined" || !(e instanceof FS.ErrnoError)) throw e;
return -e.errno;
}
}
function ___syscall_fstat64(fd, buf) {
if (ENVIRONMENT_IS_PTHREAD) return _emscripten_proxy_to_main_thread_js(12, 1, fd, buf);
try {
var stream = SYSCALLS.getStreamFromFD(fd);
return SYSCALLS.doStat(FS.stat, stream.path, buf);
} catch (e) {
if (typeof FS == "undefined" || !(e instanceof FS.ErrnoError)) throw e;
return -e.errno;
}
}
function ___syscall_statfs64(path, size, buf) {
if (ENVIRONMENT_IS_PTHREAD) return _emscripten_proxy_to_main_thread_js(14, 1, path, size, buf);
try {
path = SYSCALLS.getStr(path);
GROWABLE_HEAP_I32()[buf + 4 >> 2] = 4096;
GROWABLE_HEAP_I32()[buf + 40 >> 2] = 4096;
GROWABLE_HEAP_I32()[buf + 8 >> 2] = 1e6;
GROWABLE_HEAP_I32()[buf + 12 >> 2] = 5e5;
GROWABLE_HEAP_I32()[buf + 16 >> 2] = 5e5;
GROWABLE_HEAP_I32()[buf + 20 >> 2] = FS.nextInode;
GROWABLE_HEAP_I32()[buf + 24 >> 2] = 1e6;
GROWABLE_HEAP_I32()[buf + 28 >> 2] = 42;
GROWABLE_HEAP_I32()[buf + 44 >> 2] = 2;
GROWABLE_HEAP_I32()[buf + 36 >> 2] = 255;
return 0;
} catch (e) {
if (typeof FS == "undefined" || !(e instanceof FS.ErrnoError)) throw e;
return -e.errno;
}
}
function ___syscall_fstatfs64(fd, size, buf) {
if (ENVIRONMENT_IS_PTHREAD) return _emscripten_proxy_to_main_thread_js(13, 1, fd, size, buf);
try {
var stream = SYSCALLS.getStreamFromFD(fd);
return ___syscall_statfs64(0, size, buf);
} catch (e) {
if (typeof FS == "undefined" || !(e instanceof FS.ErrnoError)) throw e;
return -e.errno;
}
}
function convertI32PairToI53Checked(lo, hi) {
return hi + 2097152 >>> 0 < 4194305 - !!lo ? (lo >>> 0) + hi * 4294967296 : NaN;
}
function ___syscall_ftruncate64(fd, length_low, length_high) {
if (ENVIRONMENT_IS_PTHREAD) return _emscripten_proxy_to_main_thread_js(15, 1, fd, length_low, length_high);
try {
var length = convertI32PairToI53Checked(length_low, length_high);
if (isNaN(length)) return -61;
FS.ftruncate(fd, length);
return 0;
} catch (e) {
if (typeof FS == "undefined" || !(e instanceof FS.ErrnoError)) throw e;
return -e.errno;
}
}
function ___syscall_getcwd(buf, size) {
if (ENVIRONMENT_IS_PTHREAD) return _emscripten_proxy_to_main_thread_js(16, 1, buf, size);
try {
if (size === 0) return -28;
var cwd = FS.cwd();
var cwdLengthInBytes = lengthBytesUTF8(cwd) + 1;
if (size < cwdLengthInBytes) return -68;
stringToUTF8(cwd, buf, size);
return cwdLengthInBytes;
} catch (e) {
if (typeof FS == "undefined" || !(e instanceof FS.ErrnoError)) throw e;
return -e.errno;
}
}
function ___syscall_getdents64(fd, dirp, count) {
if (ENVIRONMENT_IS_PTHREAD) return _emscripten_proxy_to_main_thread_js(17, 1, fd, dirp, count);
try {
var stream = SYSCALLS.getStreamFromFD(fd);
if (!stream.getdents) {
stream.getdents = FS.readdir(stream.path);
}
var struct_size = 280;
var pos = 0;
var off = FS.llseek(stream, 0, 1);
var idx = Math.floor(off / struct_size);
while (idx < stream.getdents.length && pos + struct_size <= count) {
var id;
var type;
var name = stream.getdents[idx];
if (name === ".") {
id = stream.node.id;
type = 4;
} else if (name === "..") {
var lookup = FS.lookupPath(stream.path, {
parent: true
});
id = lookup.node.id;
type = 4;
} else {
var child = FS.lookupNode(stream.node, name);
id = child.id;
type = FS.isChrdev(child.mode) ? 2 : FS.isDir(child.mode) ? 4 : FS.isLink(child.mode) ? 10 : 8;
}
tempI64 = [ id >>> 0, (tempDouble = id, +Math.abs(tempDouble) >= 1 ? tempDouble > 0 ? (Math.min(+Math.floor(tempDouble / 4294967296), 4294967295) | 0) >>> 0 : ~~+Math.ceil((tempDouble - +(~~tempDouble >>> 0)) / 4294967296) >>> 0 : 0) ],
GROWABLE_HEAP_I32()[dirp + pos >> 2] = tempI64[0], GROWABLE_HEAP_I32()[dirp + pos + 4 >> 2] = tempI64[1];
tempI64 = [ (idx + 1) * struct_size >>> 0, (tempDouble = (idx + 1) * struct_size,
+Math.abs(tempDouble) >= 1 ? tempDouble > 0 ? (Math.min(+Math.floor(tempDouble / 4294967296), 4294967295) | 0) >>> 0 : ~~+Math.ceil((tempDouble - +(~~tempDouble >>> 0)) / 4294967296) >>> 0 : 0) ],
GROWABLE_HEAP_I32()[dirp + pos + 8 >> 2] = tempI64[0], GROWABLE_HEAP_I32()[dirp + pos + 12 >> 2] = tempI64[1];
GROWABLE_HEAP_I16()[dirp + pos + 16 >> 1] = 280;
GROWABLE_HEAP_I8()[dirp + pos + 18 >> 0] = type;
stringToUTF8(name, dirp + pos + 19, 256);
pos += struct_size;
idx += 1;
}
FS.llseek(stream, idx * struct_size, 0);
return pos;
} catch (e) {
if (typeof FS == "undefined" || !(e instanceof FS.ErrnoError)) throw e;
return -e.errno;
}
}
function ___syscall_getsockname(fd, addr, addrlen) {
if (ENVIRONMENT_IS_PTHREAD) return _emscripten_proxy_to_main_thread_js(18, 1, fd, addr, addrlen);
try {
err("__syscall_getsockname " + fd);
var sock = getSocketFromFD(fd);
var errno = writeSockaddr(addr, sock.family, DNS.lookup_name(sock.saddr || "0.0.0.0"), sock.sport, addrlen);
return 0;
} catch (e) {
if (typeof FS == "undefined" || !(e instanceof FS.ErrnoError)) throw e;
return -e.errno;
}
}
function ___syscall_ioctl(fd, op, varargs) {
if (ENVIRONMENT_IS_PTHREAD) return _emscripten_proxy_to_main_thread_js(19, 1, fd, op, varargs);
SYSCALLS.varargs = varargs;
try {
var stream = SYSCALLS.getStreamFromFD(fd);
switch (op) {
case 21509:
case 21505:
{
if (!stream.tty) return -59;
return 0;
}
case 21510:
case 21511:
case 21512:
case 21506:
case 21507:
case 21508:
{
if (!stream.tty) return -59;
return 0;
}
case 21519:
{
if (!stream.tty) return -59;
var argp = SYSCALLS.get();
GROWABLE_HEAP_I32()[argp >> 2] = 0;
return 0;
}
case 21520:
{
if (!stream.tty) return -59;
return -28;
}
case 21531:
{
var argp = SYSCALLS.get();
return FS.ioctl(stream, op, argp);
}
case 21523:
{
if (!stream.tty) return -59;
return 0;
}
case 21524:
{
if (!stream.tty) return -59;
return 0;
}
default:
abort("bad ioctl syscall " + op);
}
} catch (e) {
if (typeof FS == "undefined" || !(e instanceof FS.ErrnoError)) throw e;
return -e.errno;
}
}
function ___syscall_listen(fd, backlog) {
if (ENVIRONMENT_IS_PTHREAD) return _emscripten_proxy_to_main_thread_js(20, 1, fd, backlog);
try {
var sock = getSocketFromFD(fd);
sock.sock_ops.listen(sock, backlog);
return 0;
} catch (e) {
if (typeof FS == "undefined" || !(e instanceof FS.ErrnoError)) throw e;
return -e.errno;
}
}
function ___syscall_lstat64(path, buf) {
if (ENVIRONMENT_IS_PTHREAD) return _emscripten_proxy_to_main_thread_js(21, 1, path, buf);
try {
path = SYSCALLS.getStr(path);
return SYSCALLS.doStat(FS.lstat, path, buf);
} catch (e) {
if (typeof FS == "undefined" || !(e instanceof FS.ErrnoError)) throw e;
return -e.errno;
}
}
function ___syscall_mkdirat(dirfd, path, mode) {
if (ENVIRONMENT_IS_PTHREAD) return _emscripten_proxy_to_main_thread_js(22, 1, dirfd, path, mode);
try {
path = SYSCALLS.getStr(path);
path = SYSCALLS.calculateAt(dirfd, path);
path = PATH.normalize(path);
if (path[path.length - 1] === "/") path = path.substr(0, path.length - 1);
FS.mkdir(path, mode, 0);
return 0;
} catch (e) {
if (typeof FS == "undefined" || !(e instanceof FS.ErrnoError)) throw e;
return -e.errno;
}
}
function ___syscall_newfstatat(dirfd, path, buf, flags) {
if (ENVIRONMENT_IS_PTHREAD) return _emscripten_proxy_to_main_thread_js(23, 1, dirfd, path, buf, flags);
try {
path = SYSCALLS.getStr(path);
var nofollow = flags & 256;
var allowEmpty = flags & 4096;
flags = flags & ~4352;
path = SYSCALLS.calculateAt(dirfd, path, allowEmpty);
return SYSCALLS.doStat(nofollow ? FS.lstat : FS.stat, path, buf);
} catch (e) {
if (typeof FS == "undefined" || !(e instanceof FS.ErrnoError)) throw e;
return -e.errno;
}
}
function ___syscall_openat(dirfd, path, flags, varargs) {
if (ENVIRONMENT_IS_PTHREAD) return _emscripten_proxy_to_main_thread_js(24, 1, dirfd, path, flags, varargs);
SYSCALLS.varargs = varargs;
try {
path = SYSCALLS.getStr(path);
path = SYSCALLS.calculateAt(dirfd, path);
var mode = varargs ? SYSCALLS.get() : 0;
return FS.open(path, flags, mode).fd;
} catch (e) {
if (typeof FS == "undefined" || !(e instanceof FS.ErrnoError)) throw e;
return -e.errno;
}
}
function ___syscall_readlinkat(dirfd, path, buf, bufsize) {
if (ENVIRONMENT_IS_PTHREAD) return _emscripten_proxy_to_main_thread_js(25, 1, dirfd, path, buf, bufsize);
try {
path = SYSCALLS.getStr(path);
path = SYSCALLS.calculateAt(dirfd, path);
if (bufsize <= 0) return -28;
var ret = FS.readlink(path);
var len = Math.min(bufsize, lengthBytesUTF8(ret));
var endChar = GROWABLE_HEAP_I8()[buf + len];
stringToUTF8(ret, buf, bufsize + 1);
GROWABLE_HEAP_I8()[buf + len] = endChar;
return len;
} catch (e) {
if (typeof FS == "undefined" || !(e instanceof FS.ErrnoError)) throw e;
return -e.errno;
}
}
function ___syscall_recvfrom(fd, buf, len, flags, addr, addrlen) {
if (ENVIRONMENT_IS_PTHREAD) return _emscripten_proxy_to_main_thread_js(26, 1, fd, buf, len, flags, addr, addrlen);
try {
var sock = getSocketFromFD(fd);
var msg = sock.sock_ops.recvmsg(sock, len);
if (!msg) return 0;
if (addr) {
var errno = writeSockaddr(addr, sock.family, DNS.lookup_name(msg.addr), msg.port, addrlen);
}
GROWABLE_HEAP_U8().set(msg.buffer, buf);
return msg.buffer.byteLength;
} catch (e) {
if (typeof FS == "undefined" || !(e instanceof FS.ErrnoError)) throw e;
return -e.errno;
}
}
function ___syscall_renameat(olddirfd, oldpath, newdirfd, newpath) {
if (ENVIRONMENT_IS_PTHREAD) return _emscripten_proxy_to_main_thread_js(27, 1, olddirfd, oldpath, newdirfd, newpath);
try {
oldpath = SYSCALLS.getStr(oldpath);
newpath = SYSCALLS.getStr(newpath);
oldpath = SYSCALLS.calculateAt(olddirfd, oldpath);
newpath = SYSCALLS.calculateAt(newdirfd, newpath);
FS.rename(oldpath, newpath);
return 0;
} catch (e) {
if (typeof FS == "undefined" || !(e instanceof FS.ErrnoError)) throw e;
return -e.errno;
}
}
function ___syscall_rmdir(path) {
if (ENVIRONMENT_IS_PTHREAD) return _emscripten_proxy_to_main_thread_js(28, 1, path);
try {
path = SYSCALLS.getStr(path);
FS.rmdir(path);
return 0;
} catch (e) {
if (typeof FS == "undefined" || !(e instanceof FS.ErrnoError)) throw e;
return -e.errno;
}
}
function ___syscall_sendto(fd, message, length, flags, addr, addr_len) {
if (ENVIRONMENT_IS_PTHREAD) return _emscripten_proxy_to_main_thread_js(29, 1, fd, message, length, flags, addr, addr_len);
try {
var sock = getSocketFromFD(fd);
var dest = getSocketAddress(addr, addr_len, true);
if (!dest) {
return FS.write(sock.stream, GROWABLE_HEAP_I8(), message, length);
} else {
return sock.sock_ops.sendmsg(sock, GROWABLE_HEAP_I8(), message, length, dest.addr, dest.port);
}
} catch (e) {
if (typeof FS == "undefined" || !(e instanceof FS.ErrnoError)) throw e;
return -e.errno;
}
}
function ___syscall_socket(domain, type, protocol) {
if (ENVIRONMENT_IS_PTHREAD) return _emscripten_proxy_to_main_thread_js(30, 1, domain, type, protocol);
try {
var sock = SOCKFS.createSocket(domain, type, protocol);
return sock.stream.fd;
} catch (e) {
if (typeof FS == "undefined" || !(e instanceof FS.ErrnoError)) throw e;
return -e.errno;
}
}
function ___syscall_stat64(path, buf) {
if (ENVIRONMENT_IS_PTHREAD) return _emscripten_proxy_to_main_thread_js(31, 1, path, buf);
try {
path = SYSCALLS.getStr(path);
return SYSCALLS.doStat(FS.stat, path, buf);
} catch (e) {
if (typeof FS == "undefined" || !(e instanceof FS.ErrnoError)) throw e;
return -e.errno;
}
}
function ___syscall_symlink(target, linkpath) {
if (ENVIRONMENT_IS_PTHREAD) return _emscripten_proxy_to_main_thread_js(32, 1, target, linkpath);
try {
target = SYSCALLS.getStr(target);
linkpath = SYSCALLS.getStr(linkpath);
FS.symlink(target, linkpath);
return 0;
} catch (e) {
if (typeof FS == "undefined" || !(e instanceof FS.ErrnoError)) throw e;
return -e.errno;
}
}
function ___syscall_unlinkat(dirfd, path, flags) {
if (ENVIRONMENT_IS_PTHREAD) return _emscripten_proxy_to_main_thread_js(33, 1, dirfd, path, flags);
try {
path = SYSCALLS.getStr(path);
path = SYSCALLS.calculateAt(dirfd, path);
if (flags === 0) {
FS.unlink(path);
} else if (flags === 512) {
FS.rmdir(path);
} else {
abort("Invalid flags passed to unlinkat");
}
return 0;
} catch (e) {
if (typeof FS == "undefined" || !(e instanceof FS.ErrnoError)) throw e;
return -e.errno;
}
}
function ___syscall_utimensat(dirfd, path, times, flags) {
if (ENVIRONMENT_IS_PTHREAD) return _emscripten_proxy_to_main_thread_js(34, 1, dirfd, path, times, flags);
try {
path = SYSCALLS.getStr(path);
path = SYSCALLS.calculateAt(dirfd, path, true);
if (!times) {
var atime = Date.now();
var mtime = atime;
} else {
var seconds = GROWABLE_HEAP_I32()[times >> 2];
var nanoseconds = GROWABLE_HEAP_I32()[times + 4 >> 2];
atime = seconds * 1e3 + nanoseconds / (1e3 * 1e3);
times += 8;
seconds = GROWABLE_HEAP_I32()[times >> 2];
nanoseconds = GROWABLE_HEAP_I32()[times + 4 >> 2];
mtime = seconds * 1e3 + nanoseconds / (1e3 * 1e3);
}
FS.utime(path, atime, mtime);
return 0;
} catch (e) {
if (typeof FS == "undefined" || !(e instanceof FS.ErrnoError)) throw e;
return -e.errno;
}
}
function __dlinit(main_dso_handle) {}
var dlopenMissingError = "To use dlopen, you need enable dynamic linking, see https://github.com/emscripten-core/emscripten/wiki/Linking";
function __dlopen_js(filename, flag) {
abort(dlopenMissingError);
}
function __emscripten_date_now() {
return Date.now();
}
function __emscripten_default_pthread_stack_size() {
return 2097152;
}
var nowIsMonotonic = true;
function __emscripten_get_now_is_monotonic() {
return nowIsMonotonic;
}
function executeNotifiedProxyingQueue(queue) {
Atomics.store(GROWABLE_HEAP_I32(), queue >> 2, 1);
if (_pthread_self()) {
__emscripten_proxy_execute_task_queue(queue);
}
Atomics.compareExchange(GROWABLE_HEAP_I32(), queue >> 2, 1, 0);
}
Module["executeNotifiedProxyingQueue"] = executeNotifiedProxyingQueue;
function __emscripten_notify_task_queue(targetThreadId, currThreadId, mainThreadId, queue) {
if (targetThreadId == currThreadId) {
setTimeout(() => executeNotifiedProxyingQueue(queue));
} else if (ENVIRONMENT_IS_PTHREAD) {
postMessage({
"targetThread": targetThreadId,
"cmd": "processProxyingQueue",
"queue": queue
});
} else {
var pthread = PThread.pthreads[targetThreadId];
var worker = pthread && pthread.worker;
if (!worker) {
return;
}
worker.postMessage({
"cmd": "processProxyingQueue",
"queue": queue
});
}
return 1;
}
function __emscripten_set_offscreencanvas_size(target, width, height) {
return -1;
}
function __gmtime_js(time, tmPtr) {
var date = new Date(GROWABLE_HEAP_I32()[time >> 2] * 1e3);
GROWABLE_HEAP_I32()[tmPtr >> 2] = date.getUTCSeconds();
GROWABLE_HEAP_I32()[tmPtr + 4 >> 2] = date.getUTCMinutes();
GROWABLE_HEAP_I32()[tmPtr + 8 >> 2] = date.getUTCHours();
GROWABLE_HEAP_I32()[tmPtr + 12 >> 2] = date.getUTCDate();
GROWABLE_HEAP_I32()[tmPtr + 16 >> 2] = date.getUTCMonth();
GROWABLE_HEAP_I32()[tmPtr + 20 >> 2] = date.getUTCFullYear() - 1900;
GROWABLE_HEAP_I32()[tmPtr + 24 >> 2] = date.getUTCDay();
var start = Date.UTC(date.getUTCFullYear(), 0, 1, 0, 0, 0, 0);
var yday = (date.getTime() - start) / (1e3 * 60 * 60 * 24) | 0;
GROWABLE_HEAP_I32()[tmPtr + 28 >> 2] = yday;
}
function __localtime_js(time, tmPtr) {
var date = new Date(GROWABLE_HEAP_I32()[time >> 2] * 1e3);
GROWABLE_HEAP_I32()[tmPtr >> 2] = date.getSeconds();
GROWABLE_HEAP_I32()[tmPtr + 4 >> 2] = date.getMinutes();
GROWABLE_HEAP_I32()[tmPtr + 8 >> 2] = date.getHours();
GROWABLE_HEAP_I32()[tmPtr + 12 >> 2] = date.getDate();
GROWABLE_HEAP_I32()[tmPtr + 16 >> 2] = date.getMonth();
GROWABLE_HEAP_I32()[tmPtr + 20 >> 2] = date.getFullYear() - 1900;
GROWABLE_HEAP_I32()[tmPtr + 24 >> 2] = date.getDay();
var start = new Date(date.getFullYear(), 0, 1);
var yday = (date.getTime() - start.getTime()) / (1e3 * 60 * 60 * 24) | 0;
GROWABLE_HEAP_I32()[tmPtr + 28 >> 2] = yday;
GROWABLE_HEAP_I32()[tmPtr + 36 >> 2] = -(date.getTimezoneOffset() * 60);
var summerOffset = new Date(date.getFullYear(), 6, 1).getTimezoneOffset();
var winterOffset = start.getTimezoneOffset();
var dst = (summerOffset != winterOffset && date.getTimezoneOffset() == Math.min(winterOffset, summerOffset)) | 0;
GROWABLE_HEAP_I32()[tmPtr + 32 >> 2] = dst;
}
function __mmap_js(len, prot, flags, fd, off, allocated) {
if (ENVIRONMENT_IS_PTHREAD) return _emscripten_proxy_to_main_thread_js(35, 1, len, prot, flags, fd, off, allocated);
try {
var stream = FS.getStream(fd);
if (!stream) return -8;
var res = FS.mmap(stream, len, off, prot, flags);
var ptr = res.ptr;
GROWABLE_HEAP_I32()[allocated >> 2] = res.allocated;
return ptr;
} catch (e) {
if (typeof FS == "undefined" || !(e instanceof FS.ErrnoError)) throw e;
return -e.errno;
}
}
function __msync_js(addr, len, flags, fd) {
if (ENVIRONMENT_IS_PTHREAD) return _emscripten_proxy_to_main_thread_js(36, 1, addr, len, flags, fd);
try {
SYSCALLS.doMsync(addr, FS.getStream(fd), len, flags, 0);
return 0;
} catch (e) {
if (typeof FS == "undefined" || !(e instanceof FS.ErrnoError)) throw e;
return -e.errno;
}
}
function __munmap_js(addr, len, prot, flags, fd, offset) {
if (ENVIRONMENT_IS_PTHREAD) return _emscripten_proxy_to_main_thread_js(37, 1, addr, len, prot, flags, fd, offset);
try {
var stream = FS.getStream(fd);
if (stream) {
if (prot & 2) {
SYSCALLS.doMsync(addr, stream, len, flags, offset);
}
FS.munmap(stream);
}
} catch (e) {
if (typeof FS == "undefined" || !(e instanceof FS.ErrnoError)) throw e;
return -e.errno;
}
}
function _tzset_impl(timezone, daylight, tzname) {
if (ENVIRONMENT_IS_PTHREAD) return _emscripten_proxy_to_main_thread_js(38, 1, timezone, daylight, tzname);
var currentYear = new Date().getFullYear();
var winter = new Date(currentYear, 0, 1);
var summer = new Date(currentYear, 6, 1);
var winterOffset = winter.getTimezoneOffset();
var summerOffset = summer.getTimezoneOffset();
var stdTimezoneOffset = Math.max(winterOffset, summerOffset);
GROWABLE_HEAP_I32()[timezone >> 2] = stdTimezoneOffset * 60;
GROWABLE_HEAP_I32()[daylight >> 2] = Number(winterOffset != summerOffset);
function extractZone(date) {
var match = date.toTimeString().match(/\(([A-Za-z ]+)\)$/);
return match ? match[1] : "GMT";
}
var winterName = extractZone(winter);
var summerName = extractZone(summer);
var winterNamePtr = allocateUTF8(winterName);
var summerNamePtr = allocateUTF8(summerName);
if (summerOffset < winterOffset) {
GROWABLE_HEAP_U32()[tzname >> 2] = winterNamePtr;
GROWABLE_HEAP_U32()[tzname + 4 >> 2] = summerNamePtr;
} else {
GROWABLE_HEAP_U32()[tzname >> 2] = summerNamePtr;
GROWABLE_HEAP_U32()[tzname + 4 >> 2] = winterNamePtr;
}
}
function __tzset_js(timezone, daylight, tzname) {
if (__tzset_js.called) return;
__tzset_js.called = true;
_tzset_impl(timezone, daylight, tzname);
}
function _abort() {
abort("");
}
var DOTNET = {};
function _dotnet_browser_can_use_subtle_crypto_impl() {
return __dotnet_runtime.__linker_exports.dotnet_browser_can_use_subtle_crypto_impl.apply(__dotnet_runtime, arguments);
}
function _dotnet_browser_derive_bits() {
return __dotnet_runtime.__linker_exports.dotnet_browser_derive_bits.apply(__dotnet_runtime, arguments);
}
function _dotnet_browser_encrypt_decrypt() {
return __dotnet_runtime.__linker_exports.dotnet_browser_encrypt_decrypt.apply(__dotnet_runtime, arguments);
}
var DOTNETENTROPY = {
batchedQuotaMax: 65536,
getBatchedRandomValues: function(buffer, bufferLength) {
const needTempBuf = typeof SharedArrayBuffer !== "undefined" && Module.HEAPU8.buffer instanceof SharedArrayBuffer;
const buf = needTempBuf ? new ArrayBuffer(bufferLength) : Module.HEAPU8.buffer;
const offset = needTempBuf ? 0 : buffer;
for (let i = 0; i < bufferLength; i += this.batchedQuotaMax) {
const view = new Uint8Array(buf, offset + i, Math.min(bufferLength - i, this.batchedQuotaMax));
crypto.getRandomValues(view);
}
if (needTempBuf) {
const heapView = new Uint8Array(Module.HEAPU8.buffer, buffer, bufferLength);
heapView.set(new Uint8Array(buf));
}
}
};
function _dotnet_browser_entropy(buffer, bufferLength) {
if (typeof crypto === "object" && typeof crypto["getRandomValues"] === "function") {
DOTNETENTROPY.getBatchedRandomValues(buffer, bufferLength);
return 0;
} else {
return -1;
}
}
function _dotnet_browser_sign() {
return __dotnet_runtime.__linker_exports.dotnet_browser_sign.apply(__dotnet_runtime, arguments);
}
function _dotnet_browser_simple_digest_hash() {
return __dotnet_runtime.__linker_exports.dotnet_browser_simple_digest_hash.apply(__dotnet_runtime, arguments);
}
function _emscripten_check_blocking_allowed() {
if (ENVIRONMENT_IS_NODE) return;
if (ENVIRONMENT_IS_WORKER) return;
warnOnce("Blocking on the main thread is very dangerous, see https://emscripten.org/docs/porting/pthreads.html#blocking-on-the-main-browser-thread");
}
function getHeapMax() {
return 2147483648;
}
function _emscripten_get_heap_max() {
return getHeapMax();
}
var _emscripten_get_now;
if (ENVIRONMENT_IS_NODE) {
_emscripten_get_now = () => {
var t = process["hrtime"]();
return t[0] * 1e3 + t[1] / 1e6;
};
} else if (ENVIRONMENT_IS_PTHREAD) {
_emscripten_get_now = () => performance.now() - Module["__performance_now_clock_drift"];
} else if (typeof dateNow != "undefined") {
_emscripten_get_now = dateNow;
} else _emscripten_get_now = () => performance.now();
function _emscripten_get_now_res() {
if (ENVIRONMENT_IS_NODE) {
return 1;
} else if (typeof dateNow != "undefined") {
return 1e3;
} else return 1e3;
}
function _emscripten_memcpy_big(dest, src, num) {
GROWABLE_HEAP_U8().copyWithin(dest, src, src + num);
}
function _emscripten_num_logical_cores() {
if (ENVIRONMENT_IS_NODE) return require("os").cpus().length;
return navigator["hardwareConcurrency"];
}
function _emscripten_proxy_to_main_thread_js(index, sync) {
var numCallArgs = arguments.length - 2;
var outerArgs = arguments;
return withStackSave(function() {
var serializedNumCallArgs = numCallArgs;
var args = stackAlloc(serializedNumCallArgs * 8);
var b = args >> 3;
for (var i = 0; i < numCallArgs; i++) {
var arg = outerArgs[2 + i];
GROWABLE_HEAP_F64()[b + i] = arg;
}
return _emscripten_run_in_main_runtime_thread_js(index, serializedNumCallArgs, args, sync);
});
}
var _emscripten_receive_on_main_thread_js_callArgs = [];
function _emscripten_receive_on_main_thread_js(index, numCallArgs, args) {
_emscripten_receive_on_main_thread_js_callArgs.length = numCallArgs;
var b = args >> 3;
for (var i = 0; i < numCallArgs; i++) {
_emscripten_receive_on_main_thread_js_callArgs[i] = GROWABLE_HEAP_F64()[b + i];
}
var isEmAsmConst = index < 0;
var func = !isEmAsmConst ? proxiedFunctionTable[index] : ASM_CONSTS[-index - 1];
return func.apply(null, _emscripten_receive_on_main_thread_js_callArgs);
}
function emscripten_realloc_buffer(size) {
try {
wasmMemory.grow(size - buffer.byteLength + 65535 >>> 16);
updateGlobalBufferAndViews(wasmMemory.buffer);
return 1;
} catch (e) {}
}
function _emscripten_resize_heap(requestedSize) {
var oldSize = GROWABLE_HEAP_U8().length;
requestedSize = requestedSize >>> 0;
if (requestedSize <= oldSize) {
return false;
}
var maxHeapSize = getHeapMax();
if (requestedSize > maxHeapSize) {
return false;
}
let alignUp = (x, multiple) => x + (multiple - x % multiple) % multiple;
for (var cutDown = 1; cutDown <= 4; cutDown *= 2) {
var overGrownHeapSize = oldSize * (1 + .2 / cutDown);
overGrownHeapSize = Math.min(overGrownHeapSize, requestedSize + 100663296);
var newSize = Math.min(maxHeapSize, alignUp(Math.max(requestedSize, overGrownHeapSize), 65536));
var replacement = emscripten_realloc_buffer(newSize);
if (replacement) {
return true;
}
}
return false;
}
function _emscripten_unwind_to_js_event_loop() {
throw "unwind";
}
var ENV = {};
function getExecutableName() {
return thisProgram || "./this.program";
}
function getEnvStrings() {
if (!getEnvStrings.strings) {
var lang = (typeof navigator == "object" && navigator.languages && navigator.languages[0] || "C").replace("-", "_") + ".UTF-8";
var env = {
"USER": "web_user",
"LOGNAME": "web_user",
"PATH": "/",
"PWD": "/",
"HOME": "/home/web_user",
"LANG": lang,
"_": getExecutableName()
};
for (var x in ENV) {
if (ENV[x] === undefined) delete env[x]; else env[x] = ENV[x];
}
var strings = [];
for (var x in env) {
strings.push(x + "=" + env[x]);
}
getEnvStrings.strings = strings;
}
return getEnvStrings.strings;
}
function _environ_get(__environ, environ_buf) {
if (ENVIRONMENT_IS_PTHREAD) return _emscripten_proxy_to_main_thread_js(39, 1, __environ, environ_buf);
var bufSize = 0;
getEnvStrings().forEach(function(string, i) {
var ptr = environ_buf + bufSize;
GROWABLE_HEAP_U32()[__environ + i * 4 >> 2] = ptr;
writeAsciiToMemory(string, ptr);
bufSize += string.length + 1;
});
return 0;
}
function _environ_sizes_get(penviron_count, penviron_buf_size) {
if (ENVIRONMENT_IS_PTHREAD) return _emscripten_proxy_to_main_thread_js(40, 1, penviron_count, penviron_buf_size);
var strings = getEnvStrings();
GROWABLE_HEAP_U32()[penviron_count >> 2] = strings.length;
var bufSize = 0;
strings.forEach(function(string) {
bufSize += string.length + 1;
});
GROWABLE_HEAP_U32()[penviron_buf_size >> 2] = bufSize;
return 0;
}
function _fd_close(fd) {
if (ENVIRONMENT_IS_PTHREAD) return _emscripten_proxy_to_main_thread_js(41, 1, fd);
try {
var stream = SYSCALLS.getStreamFromFD(fd);
FS.close(stream);
return 0;
} catch (e) {
if (typeof FS == "undefined" || !(e instanceof FS.ErrnoError)) throw e;
return e.errno;
}
}
function _fd_fdstat_get(fd, pbuf) {
if (ENVIRONMENT_IS_PTHREAD) return _emscripten_proxy_to_main_thread_js(42, 1, fd, pbuf);
try {
var stream = SYSCALLS.getStreamFromFD(fd);
var type = stream.tty ? 2 : FS.isDir(stream.mode) ? 3 : FS.isLink(stream.mode) ? 7 : 4;
GROWABLE_HEAP_I8()[pbuf >> 0] = type;
return 0;
} catch (e) {
if (typeof FS == "undefined" || !(e instanceof FS.ErrnoError)) throw e;
return e.errno;
}
}
function doReadv(stream, iov, iovcnt, offset) {
var ret = 0;
for (var i = 0; i < iovcnt; i++) {
var ptr = GROWABLE_HEAP_U32()[iov >> 2];
var len = GROWABLE_HEAP_U32()[iov + 4 >> 2];
iov += 8;
var curr = FS.read(stream, GROWABLE_HEAP_I8(), ptr, len, offset);
if (curr < 0) return -1;
ret += curr;
if (curr < len) break;
}
return ret;
}
function _fd_pread(fd, iov, iovcnt, offset_low, offset_high, pnum) {
if (ENVIRONMENT_IS_PTHREAD) return _emscripten_proxy_to_main_thread_js(43, 1, fd, iov, iovcnt, offset_low, offset_high, pnum);
try {
var offset = convertI32PairToI53Checked(offset_low, offset_high);
if (isNaN(offset)) return 61;
var stream = SYSCALLS.getStreamFromFD(fd);
var num = doReadv(stream, iov, iovcnt, offset);
GROWABLE_HEAP_I32()[pnum >> 2] = num;
return 0;
} catch (e) {
if (typeof FS == "undefined" || !(e instanceof FS.ErrnoError)) throw e;
return e.errno;
}
}
function doWritev(stream, iov, iovcnt, offset) {
var ret = 0;
for (var i = 0; i < iovcnt; i++) {
var ptr = GROWABLE_HEAP_U32()[iov >> 2];
var len = GROWABLE_HEAP_U32()[iov + 4 >> 2];
iov += 8;
var curr = FS.write(stream, GROWABLE_HEAP_I8(), ptr, len, offset);
if (curr < 0) return -1;
ret += curr;
}
return ret;
}
function _fd_pwrite(fd, iov, iovcnt, offset_low, offset_high, pnum) {
if (ENVIRONMENT_IS_PTHREAD) return _emscripten_proxy_to_main_thread_js(44, 1, fd, iov, iovcnt, offset_low, offset_high, pnum);
try {
var offset = convertI32PairToI53Checked(offset_low, offset_high);
if (isNaN(offset)) return 61;
var stream = SYSCALLS.getStreamFromFD(fd);
var num = doWritev(stream, iov, iovcnt, offset);
GROWABLE_HEAP_I32()[pnum >> 2] = num;
return 0;
} catch (e) {
if (typeof FS == "undefined" || !(e instanceof FS.ErrnoError)) throw e;
return e.errno;
}
}
function _fd_read(fd, iov, iovcnt, pnum) {
if (ENVIRONMENT_IS_PTHREAD) return _emscripten_proxy_to_main_thread_js(45, 1, fd, iov, iovcnt, pnum);
try {
var stream = SYSCALLS.getStreamFromFD(fd);
var num = doReadv(stream, iov, iovcnt);
GROWABLE_HEAP_I32()[pnum >> 2] = num;
return 0;
} catch (e) {
if (typeof FS == "undefined" || !(e instanceof FS.ErrnoError)) throw e;
return e.errno;
}
}
function _fd_seek(fd, offset_low, offset_high, whence, newOffset) {
if (ENVIRONMENT_IS_PTHREAD) return _emscripten_proxy_to_main_thread_js(46, 1, fd, offset_low, offset_high, whence, newOffset);
try {
var offset = convertI32PairToI53Checked(offset_low, offset_high);
if (isNaN(offset)) return 61;
var stream = SYSCALLS.getStreamFromFD(fd);
FS.llseek(stream, offset, whence);
tempI64 = [ stream.position >>> 0, (tempDouble = stream.position, +Math.abs(tempDouble) >= 1 ? tempDouble > 0 ? (Math.min(+Math.floor(tempDouble / 4294967296), 4294967295) | 0) >>> 0 : ~~+Math.ceil((tempDouble - +(~~tempDouble >>> 0)) / 4294967296) >>> 0 : 0) ],
GROWABLE_HEAP_I32()[newOffset >> 2] = tempI64[0], GROWABLE_HEAP_I32()[newOffset + 4 >> 2] = tempI64[1];
if (stream.getdents && offset === 0 && whence === 0) stream.getdents = null;
return 0;
} catch (e) {
if (typeof FS == "undefined" || !(e instanceof FS.ErrnoError)) throw e;
return e.errno;
}
}
function _fd_sync(fd) {
if (ENVIRONMENT_IS_PTHREAD) return _emscripten_proxy_to_main_thread_js(47, 1, fd);
try {
var stream = SYSCALLS.getStreamFromFD(fd);
if (stream.stream_ops && stream.stream_ops.fsync) {
return -stream.stream_ops.fsync(stream);
}
return 0;
} catch (e) {
if (typeof FS == "undefined" || !(e instanceof FS.ErrnoError)) throw e;
return e.errno;
}
}
function _fd_write(fd, iov, iovcnt, pnum) {
if (ENVIRONMENT_IS_PTHREAD) return _emscripten_proxy_to_main_thread_js(48, 1, fd, iov, iovcnt, pnum);
try {
var stream = SYSCALLS.getStreamFromFD(fd);
var num = doWritev(stream, iov, iovcnt);
GROWABLE_HEAP_U32()[pnum >> 2] = num;
return 0;
} catch (e) {
if (typeof FS == "undefined" || !(e instanceof FS.ErrnoError)) throw e;
return e.errno;
}
}
function _getTempRet0() {
return getTempRet0();
}
function _getaddrinfo(node, service, hint, out) {
if (ENVIRONMENT_IS_PTHREAD) return _emscripten_proxy_to_main_thread_js(49, 1, node, service, hint, out);
var addrs = [];
var canon = null;
var addr = 0;
var port = 0;
var flags = 0;
var family = 0;
var type = 0;
var proto = 0;
var ai, last;
function allocaddrinfo(family, type, proto, canon, addr, port) {
var sa, salen, ai;
var errno;
salen = family === 10 ? 28 : 16;
addr = family === 10 ? inetNtop6(addr) : inetNtop4(addr);
sa = _malloc(salen);
errno = writeSockaddr(sa, family, addr, port);
assert(!errno);
ai = _malloc(32);
GROWABLE_HEAP_I32()[ai + 4 >> 2] = family;
GROWABLE_HEAP_I32()[ai + 8 >> 2] = type;
GROWABLE_HEAP_I32()[ai + 12 >> 2] = proto;
GROWABLE_HEAP_I32()[ai + 24 >> 2] = canon;
GROWABLE_HEAP_U32()[ai + 20 >> 2] = sa;
if (family === 10) {
GROWABLE_HEAP_I32()[ai + 16 >> 2] = 28;
} else {
GROWABLE_HEAP_I32()[ai + 16 >> 2] = 16;
}
GROWABLE_HEAP_I32()[ai + 28 >> 2] = 0;
return ai;
}
if (hint) {
flags = GROWABLE_HEAP_I32()[hint >> 2];
family = GROWABLE_HEAP_I32()[hint + 4 >> 2];
type = GROWABLE_HEAP_I32()[hint + 8 >> 2];
proto = GROWABLE_HEAP_I32()[hint + 12 >> 2];
}
if (type && !proto) {
proto = type === 2 ? 17 : 6;
}
if (!type && proto) {
type = proto === 17 ? 2 : 1;
}
if (proto === 0) {
proto = 6;
}
if (type === 0) {
type = 1;
}
if (!node && !service) {
return -2;
}
if (flags & ~(1 | 2 | 4 | 1024 | 8 | 16 | 32)) {
return -1;
}
if (hint !== 0 && GROWABLE_HEAP_I32()[hint >> 2] & 2 && !node) {
return -1;
}
if (flags & 32) {
return -2;
}
if (type !== 0 && type !== 1 && type !== 2) {
return -7;
}
if (family !== 0 && family !== 2 && family !== 10) {
return -6;
}
if (service) {
service = UTF8ToString(service);
port = parseInt(service, 10);
if (isNaN(port)) {
if (flags & 1024) {
return -2;
}
return -8;
}
}
if (!node) {
if (family === 0) {
family = 2;
}
if ((flags & 1) === 0) {
if (family === 2) {
addr = _htonl(2130706433);
} else {
addr = [ 0, 0, 0, 1 ];
}
}
ai = allocaddrinfo(family, type, proto, null, addr, port);
GROWABLE_HEAP_U32()[out >> 2] = ai;
return 0;
}
node = UTF8ToString(node);
addr = inetPton4(node);
if (addr !== null) {
if (family === 0 || family === 2) {
family = 2;
} else if (family === 10 && flags & 8) {
addr = [ 0, 0, _htonl(65535), addr ];
family = 10;
} else {
return -2;
}
} else {
addr = inetPton6(node);
if (addr !== null) {
if (family === 0 || family === 10) {
family = 10;
} else {
return -2;
}
}
}
if (addr != null) {
ai = allocaddrinfo(family, type, proto, node, addr, port);
GROWABLE_HEAP_U32()[out >> 2] = ai;
return 0;
}
if (flags & 4) {
return -2;
}
node = DNS.lookup_name(node);
addr = inetPton4(node);
if (family === 0) {
family = 2;
} else if (family === 10) {
addr = [ 0, 0, _htonl(65535), addr ];
}
ai = allocaddrinfo(family, type, proto, null, addr, port);
GROWABLE_HEAP_U32()[out >> 2] = ai;
return 0;
}
function _llvm_eh_typeid_for(type) {
return type;
}
function _mono_set_timeout() {
return __dotnet_runtime.__linker_exports.mono_set_timeout.apply(__dotnet_runtime, arguments);
}
function _mono_wasm_add_dbg_command_received() {
return __dotnet_runtime.__linker_exports.mono_wasm_add_dbg_command_received.apply(__dotnet_runtime, arguments);
}
function _mono_wasm_asm_loaded() {
return __dotnet_runtime.__linker_exports.mono_wasm_asm_loaded.apply(__dotnet_runtime, arguments);
}
function _mono_wasm_bind_cs_function() {
return __dotnet_runtime.__linker_exports.mono_wasm_bind_cs_function.apply(__dotnet_runtime, arguments);
}
function _mono_wasm_bind_js_function() {
return __dotnet_runtime.__linker_exports.mono_wasm_bind_js_function.apply(__dotnet_runtime, arguments);
}
function _mono_wasm_create_cs_owned_object_ref() {
return __dotnet_runtime.__linker_exports.mono_wasm_create_cs_owned_object_ref.apply(__dotnet_runtime, arguments);
}
function _mono_wasm_debugger_log() {
return __dotnet_runtime.__linker_exports.mono_wasm_debugger_log.apply(__dotnet_runtime, arguments);
}
function _mono_wasm_fire_debugger_agent_message() {
return __dotnet_runtime.__linker_exports.mono_wasm_fire_debugger_agent_message.apply(__dotnet_runtime, arguments);
}
function _mono_wasm_get_by_index_ref() {
return __dotnet_runtime.__linker_exports.mono_wasm_get_by_index_ref.apply(__dotnet_runtime, arguments);
}
function _mono_wasm_get_global_object_ref() {
return __dotnet_runtime.__linker_exports.mono_wasm_get_global_object_ref.apply(__dotnet_runtime, arguments);
}
function _mono_wasm_get_object_property_ref() {
return __dotnet_runtime.__linker_exports.mono_wasm_get_object_property_ref.apply(__dotnet_runtime, arguments);
}
function _mono_wasm_invoke_bound_function() {
return __dotnet_runtime.__linker_exports.mono_wasm_invoke_bound_function.apply(__dotnet_runtime, arguments);
}
function _mono_wasm_invoke_js_blazor() {
return __dotnet_runtime.__linker_exports.mono_wasm_invoke_js_blazor.apply(__dotnet_runtime, arguments);
}
function _mono_wasm_invoke_js_with_args_ref() {
return __dotnet_runtime.__linker_exports.mono_wasm_invoke_js_with_args_ref.apply(__dotnet_runtime, arguments);
}
function _mono_wasm_marshal_promise() {
return __dotnet_runtime.__linker_exports.mono_wasm_marshal_promise.apply(__dotnet_runtime, arguments);
}
function _mono_wasm_pthread_on_pthread_attached() {
return __dotnet_runtime.__linker_exports.mono_wasm_pthread_on_pthread_attached.apply(__dotnet_runtime, arguments);
}
function _mono_wasm_release_cs_owned_object() {
return __dotnet_runtime.__linker_exports.mono_wasm_release_cs_owned_object.apply(__dotnet_runtime, arguments);
}
function _mono_wasm_set_by_index_ref() {
return __dotnet_runtime.__linker_exports.mono_wasm_set_by_index_ref.apply(__dotnet_runtime, arguments);
}
function _mono_wasm_set_entrypoint_breakpoint() {
return __dotnet_runtime.__linker_exports.mono_wasm_set_entrypoint_breakpoint.apply(__dotnet_runtime, arguments);
}
function _mono_wasm_set_object_property_ref() {
return __dotnet_runtime.__linker_exports.mono_wasm_set_object_property_ref.apply(__dotnet_runtime, arguments);
}
function _mono_wasm_trace_logger() {
return __dotnet_runtime.__linker_exports.mono_wasm_trace_logger.apply(__dotnet_runtime, arguments);
}
function _mono_wasm_typed_array_copy_from_ref() {
return __dotnet_runtime.__linker_exports.mono_wasm_typed_array_copy_from_ref.apply(__dotnet_runtime, arguments);
}
function _mono_wasm_typed_array_copy_to_ref() {
return __dotnet_runtime.__linker_exports.mono_wasm_typed_array_copy_to_ref.apply(__dotnet_runtime, arguments);
}
function _mono_wasm_typed_array_from_ref() {
return __dotnet_runtime.__linker_exports.mono_wasm_typed_array_from_ref.apply(__dotnet_runtime, arguments);
}
function _mono_wasm_typed_array_to_array_ref() {
return __dotnet_runtime.__linker_exports.mono_wasm_typed_array_to_array_ref.apply(__dotnet_runtime, arguments);
}
function _schedule_background_exec() {
return __dotnet_runtime.__linker_exports.schedule_background_exec.apply(__dotnet_runtime, arguments);
}
function _setTempRet0(val) {
setTempRet0(val);
}
function __isLeapYear(year) {
return year % 4 === 0 && (year % 100 !== 0 || year % 400 === 0);
}
function __arraySum(array, index) {
var sum = 0;
for (var i = 0; i <= index; sum += array[i++]) {}
return sum;
}
var __MONTH_DAYS_LEAP = [ 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 ];
var __MONTH_DAYS_REGULAR = [ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 ];
function __addDays(date, days) {
var newDate = new Date(date.getTime());
while (days > 0) {
var leap = __isLeapYear(newDate.getFullYear());
var currentMonth = newDate.getMonth();
var daysInCurrentMonth = (leap ? __MONTH_DAYS_LEAP : __MONTH_DAYS_REGULAR)[currentMonth];
if (days > daysInCurrentMonth - newDate.getDate()) {
days -= daysInCurrentMonth - newDate.getDate() + 1;
newDate.setDate(1);
if (currentMonth < 11) {
newDate.setMonth(currentMonth + 1);
} else {
newDate.setMonth(0);
newDate.setFullYear(newDate.getFullYear() + 1);
}
} else {
newDate.setDate(newDate.getDate() + days);
return newDate;
}
}
return newDate;
}
function _strftime(s, maxsize, format, tm) {
var tm_zone = GROWABLE_HEAP_I32()[tm + 40 >> 2];
var date = {
tm_sec: GROWABLE_HEAP_I32()[tm >> 2],
tm_min: GROWABLE_HEAP_I32()[tm + 4 >> 2],
tm_hour: GROWABLE_HEAP_I32()[tm + 8 >> 2],
tm_mday: GROWABLE_HEAP_I32()[tm + 12 >> 2],
tm_mon: GROWABLE_HEAP_I32()[tm + 16 >> 2],
tm_year: GROWABLE_HEAP_I32()[tm + 20 >> 2],
tm_wday: GROWABLE_HEAP_I32()[tm + 24 >> 2],
tm_yday: GROWABLE_HEAP_I32()[tm + 28 >> 2],
tm_isdst: GROWABLE_HEAP_I32()[tm + 32 >> 2],
tm_gmtoff: GROWABLE_HEAP_I32()[tm + 36 >> 2],
tm_zone: tm_zone ? UTF8ToString(tm_zone) : ""
};
var pattern = UTF8ToString(format);
var EXPANSION_RULES_1 = {
"%c": "%a %b %d %H:%M:%S %Y",
"%D": "%m/%d/%y",
"%F": "%Y-%m-%d",
"%h": "%b",
"%r": "%I:%M:%S %p",
"%R": "%H:%M",
"%T": "%H:%M:%S",
"%x": "%m/%d/%y",
"%X": "%H:%M:%S",
"%Ec": "%c",
"%EC": "%C",
"%Ex": "%m/%d/%y",
"%EX": "%H:%M:%S",
"%Ey": "%y",
"%EY": "%Y",
"%Od": "%d",
"%Oe": "%e",
"%OH": "%H",
"%OI": "%I",
"%Om": "%m",
"%OM": "%M",
"%OS": "%S",
"%Ou": "%u",
"%OU": "%U",
"%OV": "%V",
"%Ow": "%w",
"%OW": "%W",
"%Oy": "%y"
};
for (var rule in EXPANSION_RULES_1) {
pattern = pattern.replace(new RegExp(rule, "g"), EXPANSION_RULES_1[rule]);
}
var WEEKDAYS = [ "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" ];
var MONTHS = [ "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" ];
function leadingSomething(value, digits, character) {
var str = typeof value == "number" ? value.toString() : value || "";
while (str.length < digits) {
str = character[0] + str;
}
return str;
}
function leadingNulls(value, digits) {
return leadingSomething(value, digits, "0");
}
function compareByDay(date1, date2) {
function sgn(value) {
return value < 0 ? -1 : value > 0 ? 1 : 0;
}
var compare;
if ((compare = sgn(date1.getFullYear() - date2.getFullYear())) === 0) {
if ((compare = sgn(date1.getMonth() - date2.getMonth())) === 0) {
compare = sgn(date1.getDate() - date2.getDate());
}
}
return compare;
}
function getFirstWeekStartDate(janFourth) {
switch (janFourth.getDay()) {
case 0:
return new Date(janFourth.getFullYear() - 1, 11, 29);
case 1:
return janFourth;
case 2:
return new Date(janFourth.getFullYear(), 0, 3);
case 3:
return new Date(janFourth.getFullYear(), 0, 2);
case 4:
return new Date(janFourth.getFullYear(), 0, 1);
case 5:
return new Date(janFourth.getFullYear() - 1, 11, 31);
case 6:
return new Date(janFourth.getFullYear() - 1, 11, 30);
}
}
function getWeekBasedYear(date) {
var thisDate = __addDays(new Date(date.tm_year + 1900, 0, 1), date.tm_yday);
var janFourthThisYear = new Date(thisDate.getFullYear(), 0, 4);
var janFourthNextYear = new Date(thisDate.getFullYear() + 1, 0, 4);
var firstWeekStartThisYear = getFirstWeekStartDate(janFourthThisYear);
var firstWeekStartNextYear = getFirstWeekStartDate(janFourthNextYear);
if (compareByDay(firstWeekStartThisYear, thisDate) <= 0) {
if (compareByDay(firstWeekStartNextYear, thisDate) <= 0) {
return thisDate.getFullYear() + 1;
} else {
return thisDate.getFullYear();
}
} else {
return thisDate.getFullYear() - 1;
}
}
var EXPANSION_RULES_2 = {
"%a": function(date) {
return WEEKDAYS[date.tm_wday].substring(0, 3);
},
"%A": function(date) {
return WEEKDAYS[date.tm_wday];
},
"%b": function(date) {
return MONTHS[date.tm_mon].substring(0, 3);
},
"%B": function(date) {
return MONTHS[date.tm_mon];
},
"%C": function(date) {
var year = date.tm_year + 1900;
return leadingNulls(year / 100 | 0, 2);
},
"%d": function(date) {
return leadingNulls(date.tm_mday, 2);
},
"%e": function(date) {
return leadingSomething(date.tm_mday, 2, " ");
},
"%g": function(date) {
return getWeekBasedYear(date).toString().substring(2);
},
"%G": function(date) {
return getWeekBasedYear(date);
},
"%H": function(date) {
return leadingNulls(date.tm_hour, 2);
},
"%I": function(date) {
var twelveHour = date.tm_hour;
if (twelveHour == 0) twelveHour = 12; else if (twelveHour > 12) twelveHour -= 12;
return leadingNulls(twelveHour, 2);
},
"%j": function(date) {
return leadingNulls(date.tm_mday + __arraySum(__isLeapYear(date.tm_year + 1900) ? __MONTH_DAYS_LEAP : __MONTH_DAYS_REGULAR, date.tm_mon - 1), 3);
},
"%m": function(date) {
return leadingNulls(date.tm_mon + 1, 2);
},
"%M": function(date) {
return leadingNulls(date.tm_min, 2);
},
"%n": function() {
return "\n";
},
"%p": function(date) {
if (date.tm_hour >= 0 && date.tm_hour < 12) {
return "AM";
} else {
return "PM";
}
},
"%S": function(date) {
return leadingNulls(date.tm_sec, 2);
},
"%t": function() {
return "\t";
},
"%u": function(date) {
return date.tm_wday || 7;
},
"%U": function(date) {
var days = date.tm_yday + 7 - date.tm_wday;
return leadingNulls(Math.floor(days / 7), 2);
},
"%V": function(date) {
var val = Math.floor((date.tm_yday + 7 - (date.tm_wday + 6) % 7) / 7);
if ((date.tm_wday + 371 - date.tm_yday - 2) % 7 <= 2) {
val++;
}
if (!val) {
val = 52;
var dec31 = (date.tm_wday + 7 - date.tm_yday - 1) % 7;
if (dec31 == 4 || dec31 == 5 && __isLeapYear(date.tm_year % 400 - 1)) {
val++;
}
} else if (val == 53) {
var jan1 = (date.tm_wday + 371 - date.tm_yday) % 7;
if (jan1 != 4 && (jan1 != 3 || !__isLeapYear(date.tm_year))) val = 1;
}
return leadingNulls(val, 2);
},
"%w": function(date) {
return date.tm_wday;
},
"%W": function(date) {
var days = date.tm_yday + 7 - (date.tm_wday + 6) % 7;
return leadingNulls(Math.floor(days / 7), 2);
},
"%y": function(date) {
return (date.tm_year + 1900).toString().substring(2);
},
"%Y": function(date) {
return date.tm_year + 1900;
},
"%z": function(date) {
var off = date.tm_gmtoff;
var ahead = off >= 0;
off = Math.abs(off) / 60;
off = off / 60 * 100 + off % 60;
return (ahead ? "+" : "-") + String("0000" + off).slice(-4);
},
"%Z": function(date) {
return date.tm_zone;
},
"%%": function() {
return "%";
}
};
pattern = pattern.replace(/%%/g, "\0\0");
for (var rule in EXPANSION_RULES_2) {
if (pattern.includes(rule)) {
pattern = pattern.replace(new RegExp(rule, "g"), EXPANSION_RULES_2[rule](date));
}
}
pattern = pattern.replace(/\0\0/g, "%");
var bytes = intArrayFromString(pattern, false);
if (bytes.length > maxsize) {
return 0;
}
writeArrayToMemory(bytes, s);
return bytes.length - 1;
}
PThread.init();
var FSNode = function(parent, name, mode, rdev) {
if (!parent) {
parent = this;
}
this.parent = parent;
this.mount = parent.mount;
this.mounted = null;
this.id = FS.nextInode++;
this.name = name;
this.mode = mode;
this.node_ops = {};
this.stream_ops = {};
this.rdev = rdev;
};
var readMode = 292 | 73;
var writeMode = 146;
Object.defineProperties(FSNode.prototype, {
read: {
get: function() {
return (this.mode & readMode) === readMode;
},
set: function(val) {
val ? this.mode |= readMode : this.mode &= ~readMode;
}
},
write: {
get: function() {
return (this.mode & writeMode) === writeMode;
},
set: function(val) {
val ? this.mode |= writeMode : this.mode &= ~writeMode;
}
},
isFolder: {
get: function() {
return FS.isDir(this.mode);
}
},
isDevice: {
get: function() {
return FS.isChrdev(this.mode);
}
}
});
FS.FSNode = FSNode;
FS.staticInit();
Module["FS_createPath"] = FS.createPath;
Module["FS_createDataFile"] = FS.createDataFile;
Module["FS_readFile"] = FS.readFile;
Module["FS_createPath"] = FS.createPath;
Module["FS_createDataFile"] = FS.createDataFile;
Module["FS_createPreloadedFile"] = FS.createPreloadedFile;
Module["FS_unlink"] = FS.unlink;
Module["FS_createLazyFile"] = FS.createLazyFile;
Module["FS_createDevice"] = FS.createDevice;
let __dotnet_replacement_PThread = true ? {} : undefined;
if (true) {
__dotnet_replacement_PThread.loadWasmModuleToWorker = PThread.loadWasmModuleToWorker;
__dotnet_replacement_PThread.threadInitTLS = PThread.threadInitTLS;
}
let __dotnet_replacements = {
scriptUrl: import.meta.url,
fetch: globalThis.fetch,
require: require,
updateGlobalBufferAndViews: updateGlobalBufferAndViews,
pthreadReplacements: __dotnet_replacement_PThread
};
if (ENVIRONMENT_IS_NODE) {
__dotnet_replacements.requirePromise = import("module").then(mod => mod.createRequire(import.meta.url));
}
let __dotnet_exportedAPI = __dotnet_runtime.__initializeImportsAndExports({
isESM: true,
isGlobal: false,
isNode: ENVIRONMENT_IS_NODE,
isWorker: ENVIRONMENT_IS_WORKER,
isShell: ENVIRONMENT_IS_SHELL,
isWeb: ENVIRONMENT_IS_WEB,
isPThread: ENVIRONMENT_IS_PTHREAD,
quit_: quit_,
ExitStatus: ExitStatus,
requirePromise: __dotnet_replacements.requirePromise
}, {
mono: MONO,
binding: BINDING,
internal: INTERNAL,
module: Module,
marshaled_exports: EXPORTS,
marshaled_imports: IMPORTS
}, __dotnet_replacements);
updateGlobalBufferAndViews = __dotnet_replacements.updateGlobalBufferAndViews;
var fetch = __dotnet_replacements.fetch;
_scriptDir = __dirname = scriptDirectory = __dotnet_replacements.scriptDirectory;
if (ENVIRONMENT_IS_NODE) {
__dotnet_replacements.requirePromise.then(someRequire => {
require = someRequire;
});
}
var noExitRuntime = __dotnet_replacements.noExitRuntime;
if (true) {
PThread.loadWasmModuleToWorker = __dotnet_replacements.pthreadReplacements.loadWasmModuleToWorker;
PThread.threadInitTLS = __dotnet_replacements.pthreadReplacements.threadInitTLS;
}
var proxiedFunctionTable = [ null, exitOnMainThread, pthreadCreateProxied, ___syscall__newselect, ___syscall_accept4, ___syscall_bind, ___syscall_chdir, ___syscall_chmod, ___syscall_connect, ___syscall_faccessat, ___syscall_fchmod, ___syscall_fcntl64, ___syscall_fstat64, ___syscall_fstatfs64, ___syscall_statfs64, ___syscall_ftruncate64, ___syscall_getcwd, ___syscall_getdents64, ___syscall_getsockname, ___syscall_ioctl, ___syscall_listen, ___syscall_lstat64, ___syscall_mkdirat, ___syscall_newfstatat, ___syscall_openat, ___syscall_readlinkat, ___syscall_recvfrom, ___syscall_renameat, ___syscall_rmdir, ___syscall_sendto, ___syscall_socket, ___syscall_stat64, ___syscall_symlink, ___syscall_unlinkat, ___syscall_utimensat, __mmap_js, __msync_js, __munmap_js, _tzset_impl, _environ_get, _environ_sizes_get, _fd_close, _fd_fdstat_get, _fd_pread, _fd_pwrite, _fd_read, _fd_seek, _fd_sync, _fd_write, _getaddrinfo ];
var ASSERTIONS = false;
function intArrayFromString(stringy, dontAddNull, length) {
var len = length > 0 ? length : lengthBytesUTF8(stringy) + 1;
var u8array = new Array(len);
var numBytesWritten = stringToUTF8Array(stringy, u8array, 0, u8array.length);
if (dontAddNull) u8array.length = numBytesWritten;
return u8array;
}
function intArrayToString(array) {
var ret = [];
for (var i = 0; i < array.length; i++) {
var chr = array[i];
if (chr > 255) {
if (ASSERTIONS) {
assert(false, "Character code " + chr + " (" + String.fromCharCode(chr) + ") at offset " + i + " not in 0x00-0xFF.");
}
chr &= 255;
}
ret.push(String.fromCharCode(chr));
}
return ret.join("");
}
var decodeBase64 = typeof atob == "function" ? atob : function(input) {
var keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
var output = "";
var chr1, chr2, chr3;
var enc1, enc2, enc3, enc4;
var i = 0;
input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");
do {
enc1 = keyStr.indexOf(input.charAt(i++));
enc2 = keyStr.indexOf(input.charAt(i++));
enc3 = keyStr.indexOf(input.charAt(i++));
enc4 = keyStr.indexOf(input.charAt(i++));
chr1 = enc1 << 2 | enc2 >> 4;
chr2 = (enc2 & 15) << 4 | enc3 >> 2;
chr3 = (enc3 & 3) << 6 | enc4;
output = output + String.fromCharCode(chr1);
if (enc3 !== 64) {
output = output + String.fromCharCode(chr2);
}
if (enc4 !== 64) {
output = output + String.fromCharCode(chr3);
}
} while (i < input.length);
return output;
};
function intArrayFromBase64(s) {
if (typeof ENVIRONMENT_IS_NODE == "boolean" && ENVIRONMENT_IS_NODE) {
var buf = Buffer.from(s, "base64");
return new Uint8Array(buf["buffer"], buf["byteOffset"], buf["byteLength"]);
}
try {
var decoded = decodeBase64(s);
var bytes = new Uint8Array(decoded.length);
for (var i = 0; i < decoded.length; ++i) {
bytes[i] = decoded.charCodeAt(i);
}
return bytes;
} catch (_) {
throw new Error("Converting base64 string to bytes failed.");
}
}
function tryParseAsDataURI(filename) {
if (!isDataURI(filename)) {
return;
}
return intArrayFromBase64(filename.slice(dataURIPrefix.length));
}
var asmLibraryArg = {
"__assert_fail": ___assert_fail,
"__cxa_allocate_exception": ___cxa_allocate_exception,
"__cxa_begin_catch": ___cxa_begin_catch,
"__cxa_end_catch": ___cxa_end_catch,
"__cxa_find_matching_catch_3": ___cxa_find_matching_catch_3,
"__cxa_throw": ___cxa_throw,
"__emscripten_init_main_thread_js": ___emscripten_init_main_thread_js,
"__emscripten_thread_cleanup": ___emscripten_thread_cleanup,
"__pthread_create_js": ___pthread_create_js,
"__resumeException": ___resumeException,
"__syscall__newselect": ___syscall__newselect,
"__syscall_accept4": ___syscall_accept4,
"__syscall_bind": ___syscall_bind,
"__syscall_chdir": ___syscall_chdir,
"__syscall_chmod": ___syscall_chmod,
"__syscall_connect": ___syscall_connect,
"__syscall_faccessat": ___syscall_faccessat,
"__syscall_fadvise64": ___syscall_fadvise64,
"__syscall_fchmod": ___syscall_fchmod,
"__syscall_fcntl64": ___syscall_fcntl64,
"__syscall_fstat64": ___syscall_fstat64,
"__syscall_fstatfs64": ___syscall_fstatfs64,
"__syscall_ftruncate64": ___syscall_ftruncate64,
"__syscall_getcwd": ___syscall_getcwd,
"__syscall_getdents64": ___syscall_getdents64,
"__syscall_getsockname": ___syscall_getsockname,
"__syscall_ioctl": ___syscall_ioctl,
"__syscall_listen": ___syscall_listen,
"__syscall_lstat64": ___syscall_lstat64,
"__syscall_mkdirat": ___syscall_mkdirat,
"__syscall_newfstatat": ___syscall_newfstatat,
"__syscall_openat": ___syscall_openat,
"__syscall_readlinkat": ___syscall_readlinkat,
"__syscall_recvfrom": ___syscall_recvfrom,
"__syscall_renameat": ___syscall_renameat,
"__syscall_rmdir": ___syscall_rmdir,
"__syscall_sendto": ___syscall_sendto,
"__syscall_socket": ___syscall_socket,
"__syscall_stat64": ___syscall_stat64,
"__syscall_symlink": ___syscall_symlink,
"__syscall_unlinkat": ___syscall_unlinkat,
"__syscall_utimensat": ___syscall_utimensat,
"_dlinit": __dlinit,
"_dlopen_js": __dlopen_js,
"_emscripten_date_now": __emscripten_date_now,
"_emscripten_default_pthread_stack_size": __emscripten_default_pthread_stack_size,
"_emscripten_get_now_is_monotonic": __emscripten_get_now_is_monotonic,
"_emscripten_notify_task_queue": __emscripten_notify_task_queue,
"_emscripten_set_offscreencanvas_size": __emscripten_set_offscreencanvas_size,
"_gmtime_js": __gmtime_js,
"_localtime_js": __localtime_js,
"_mmap_js": __mmap_js,
"_msync_js": __msync_js,
"_munmap_js": __munmap_js,
"_tzset_js": __tzset_js,
"abort": _abort,
"dotnet_browser_can_use_subtle_crypto_impl": _dotnet_browser_can_use_subtle_crypto_impl,
"dotnet_browser_derive_bits": _dotnet_browser_derive_bits,
"dotnet_browser_encrypt_decrypt": _dotnet_browser_encrypt_decrypt,
"dotnet_browser_entropy": _dotnet_browser_entropy,
"dotnet_browser_sign": _dotnet_browser_sign,
"dotnet_browser_simple_digest_hash": _dotnet_browser_simple_digest_hash,
"emscripten_check_blocking_allowed": _emscripten_check_blocking_allowed,
"emscripten_get_heap_max": _emscripten_get_heap_max,
"emscripten_get_now": _emscripten_get_now,
"emscripten_get_now_res": _emscripten_get_now_res,
"emscripten_memcpy_big": _emscripten_memcpy_big,
"emscripten_num_logical_cores": _emscripten_num_logical_cores,
"emscripten_receive_on_main_thread_js": _emscripten_receive_on_main_thread_js,
"emscripten_resize_heap": _emscripten_resize_heap,
"emscripten_unwind_to_js_event_loop": _emscripten_unwind_to_js_event_loop,
"environ_get": _environ_get,
"environ_sizes_get": _environ_sizes_get,
"exit": _exit,
"fd_close": _fd_close,
"fd_fdstat_get": _fd_fdstat_get,
"fd_pread": _fd_pread,
"fd_pwrite": _fd_pwrite,
"fd_read": _fd_read,
"fd_seek": _fd_seek,
"fd_sync": _fd_sync,
"fd_write": _fd_write,
"getTempRet0": _getTempRet0,
"getaddrinfo": _getaddrinfo,
"invoke_vi": invoke_vi,
"llvm_eh_typeid_for": _llvm_eh_typeid_for,
"memory": wasmMemory || Module["wasmMemory"],
"mono_set_timeout": _mono_set_timeout,
"mono_wasm_add_dbg_command_received": _mono_wasm_add_dbg_command_received,
"mono_wasm_asm_loaded": _mono_wasm_asm_loaded,
"mono_wasm_bind_cs_function": _mono_wasm_bind_cs_function,
"mono_wasm_bind_js_function": _mono_wasm_bind_js_function,
"mono_wasm_create_cs_owned_object_ref": _mono_wasm_create_cs_owned_object_ref,
"mono_wasm_debugger_log": _mono_wasm_debugger_log,
"mono_wasm_fire_debugger_agent_message": _mono_wasm_fire_debugger_agent_message,
"mono_wasm_get_by_index_ref": _mono_wasm_get_by_index_ref,
"mono_wasm_get_global_object_ref": _mono_wasm_get_global_object_ref,
"mono_wasm_get_object_property_ref": _mono_wasm_get_object_property_ref,
"mono_wasm_invoke_bound_function": _mono_wasm_invoke_bound_function,
"mono_wasm_invoke_js_blazor": _mono_wasm_invoke_js_blazor,
"mono_wasm_invoke_js_with_args_ref": _mono_wasm_invoke_js_with_args_ref,
"mono_wasm_marshal_promise": _mono_wasm_marshal_promise,
"mono_wasm_pthread_on_pthread_attached": _mono_wasm_pthread_on_pthread_attached,
"mono_wasm_release_cs_owned_object": _mono_wasm_release_cs_owned_object,
"mono_wasm_set_by_index_ref": _mono_wasm_set_by_index_ref,
"mono_wasm_set_entrypoint_breakpoint": _mono_wasm_set_entrypoint_breakpoint,
"mono_wasm_set_object_property_ref": _mono_wasm_set_object_property_ref,
"mono_wasm_trace_logger": _mono_wasm_trace_logger,
"mono_wasm_typed_array_copy_from_ref": _mono_wasm_typed_array_copy_from_ref,
"mono_wasm_typed_array_copy_to_ref": _mono_wasm_typed_array_copy_to_ref,
"mono_wasm_typed_array_from_ref": _mono_wasm_typed_array_from_ref,
"mono_wasm_typed_array_to_array_ref": _mono_wasm_typed_array_to_array_ref,
"schedule_background_exec": _schedule_background_exec,
"setTempRet0": _setTempRet0,
"strftime": _strftime
};
var asm = createWasm();
var ___wasm_call_ctors = Module["___wasm_call_ctors"] = function() {
return (___wasm_call_ctors = Module["___wasm_call_ctors"] = Module["asm"]["__wasm_call_ctors"]).apply(null, arguments);
};
var _mono_wasm_register_root = Module["_mono_wasm_register_root"] = function() {
return (_mono_wasm_register_root = Module["_mono_wasm_register_root"] = Module["asm"]["mono_wasm_register_root"]).apply(null, arguments);
};
var _mono_wasm_deregister_root = Module["_mono_wasm_deregister_root"] = function() {
return (_mono_wasm_deregister_root = Module["_mono_wasm_deregister_root"] = Module["asm"]["mono_wasm_deregister_root"]).apply(null, arguments);
};
var _mono_wasm_typed_array_new_ref = Module["_mono_wasm_typed_array_new_ref"] = function() {
return (_mono_wasm_typed_array_new_ref = Module["_mono_wasm_typed_array_new_ref"] = Module["asm"]["mono_wasm_typed_array_new_ref"]).apply(null, arguments);
};
var _mono_wasm_unbox_enum = Module["_mono_wasm_unbox_enum"] = function() {
return (_mono_wasm_unbox_enum = Module["_mono_wasm_unbox_enum"] = Module["asm"]["mono_wasm_unbox_enum"]).apply(null, arguments);
};
var _mono_wasm_add_assembly = Module["_mono_wasm_add_assembly"] = function() {
return (_mono_wasm_add_assembly = Module["_mono_wasm_add_assembly"] = Module["asm"]["mono_wasm_add_assembly"]).apply(null, arguments);
};
var _mono_wasm_add_satellite_assembly = Module["_mono_wasm_add_satellite_assembly"] = function() {
return (_mono_wasm_add_satellite_assembly = Module["_mono_wasm_add_satellite_assembly"] = Module["asm"]["mono_wasm_add_satellite_assembly"]).apply(null, arguments);
};
var _mono_wasm_setenv = Module["_mono_wasm_setenv"] = function() {
return (_mono_wasm_setenv = Module["_mono_wasm_setenv"] = Module["asm"]["mono_wasm_setenv"]).apply(null, arguments);
};
var _mono_wasm_register_bundled_satellite_assemblies = Module["_mono_wasm_register_bundled_satellite_assemblies"] = function() {
return (_mono_wasm_register_bundled_satellite_assemblies = Module["_mono_wasm_register_bundled_satellite_assemblies"] = Module["asm"]["mono_wasm_register_bundled_satellite_assemblies"]).apply(null, arguments);
};
var _free = Module["_free"] = function() {
return (_free = Module["_free"] = Module["asm"]["free"]).apply(null, arguments);
};
var _mono_wasm_load_runtime = Module["_mono_wasm_load_runtime"] = function() {
return (_mono_wasm_load_runtime = Module["_mono_wasm_load_runtime"] = Module["asm"]["mono_wasm_load_runtime"]).apply(null, arguments);
};
var _malloc = Module["_malloc"] = function() {
return (_malloc = Module["_malloc"] = Module["asm"]["malloc"]).apply(null, arguments);
};
var _mono_wasm_assembly_load = Module["_mono_wasm_assembly_load"] = function() {
return (_mono_wasm_assembly_load = Module["_mono_wasm_assembly_load"] = Module["asm"]["mono_wasm_assembly_load"]).apply(null, arguments);
};
var _mono_wasm_get_corlib = Module["_mono_wasm_get_corlib"] = function() {
return (_mono_wasm_get_corlib = Module["_mono_wasm_get_corlib"] = Module["asm"]["mono_wasm_get_corlib"]).apply(null, arguments);
};
var _mono_wasm_assembly_find_class = Module["_mono_wasm_assembly_find_class"] = function() {
return (_mono_wasm_assembly_find_class = Module["_mono_wasm_assembly_find_class"] = Module["asm"]["mono_wasm_assembly_find_class"]).apply(null, arguments);
};
var _mono_wasm_runtime_run_module_cctor = Module["_mono_wasm_runtime_run_module_cctor"] = function() {
return (_mono_wasm_runtime_run_module_cctor = Module["_mono_wasm_runtime_run_module_cctor"] = Module["asm"]["mono_wasm_runtime_run_module_cctor"]).apply(null, arguments);
};
var _mono_wasm_assembly_find_method = Module["_mono_wasm_assembly_find_method"] = function() {
return (_mono_wasm_assembly_find_method = Module["_mono_wasm_assembly_find_method"] = Module["asm"]["mono_wasm_assembly_find_method"]).apply(null, arguments);
};
var _mono_wasm_get_delegate_invoke_ref = Module["_mono_wasm_get_delegate_invoke_ref"] = function() {
return (_mono_wasm_get_delegate_invoke_ref = Module["_mono_wasm_get_delegate_invoke_ref"] = Module["asm"]["mono_wasm_get_delegate_invoke_ref"]).apply(null, arguments);
};
var _mono_wasm_box_primitive_ref = Module["_mono_wasm_box_primitive_ref"] = function() {
return (_mono_wasm_box_primitive_ref = Module["_mono_wasm_box_primitive_ref"] = Module["asm"]["mono_wasm_box_primitive_ref"]).apply(null, arguments);
};
var _mono_wasm_invoke_method_ref = Module["_mono_wasm_invoke_method_ref"] = function() {
return (_mono_wasm_invoke_method_ref = Module["_mono_wasm_invoke_method_ref"] = Module["asm"]["mono_wasm_invoke_method_ref"]).apply(null, arguments);
};
var _mono_wasm_invoke_method_bound = Module["_mono_wasm_invoke_method_bound"] = function() {
return (_mono_wasm_invoke_method_bound = Module["_mono_wasm_invoke_method_bound"] = Module["asm"]["mono_wasm_invoke_method_bound"]).apply(null, arguments);
};
var _mono_wasm_assembly_get_entry_point = Module["_mono_wasm_assembly_get_entry_point"] = function() {
return (_mono_wasm_assembly_get_entry_point = Module["_mono_wasm_assembly_get_entry_point"] = Module["asm"]["mono_wasm_assembly_get_entry_point"]).apply(null, arguments);
};
var _mono_wasm_string_get_utf8 = Module["_mono_wasm_string_get_utf8"] = function() {
return (_mono_wasm_string_get_utf8 = Module["_mono_wasm_string_get_utf8"] = Module["asm"]["mono_wasm_string_get_utf8"]).apply(null, arguments);
};
var _mono_wasm_string_from_js = Module["_mono_wasm_string_from_js"] = function() {
return (_mono_wasm_string_from_js = Module["_mono_wasm_string_from_js"] = Module["asm"]["mono_wasm_string_from_js"]).apply(null, arguments);
};
var _mono_wasm_string_from_utf16_ref = Module["_mono_wasm_string_from_utf16_ref"] = function() {
return (_mono_wasm_string_from_utf16_ref = Module["_mono_wasm_string_from_utf16_ref"] = Module["asm"]["mono_wasm_string_from_utf16_ref"]).apply(null, arguments);
};
var _mono_wasm_get_obj_class = Module["_mono_wasm_get_obj_class"] = function() {
return (_mono_wasm_get_obj_class = Module["_mono_wasm_get_obj_class"] = Module["asm"]["mono_wasm_get_obj_class"]).apply(null, arguments);
};
var _mono_wasm_get_obj_type = Module["_mono_wasm_get_obj_type"] = function() {
return (_mono_wasm_get_obj_type = Module["_mono_wasm_get_obj_type"] = Module["asm"]["mono_wasm_get_obj_type"]).apply(null, arguments);
};
var _mono_wasm_try_unbox_primitive_and_get_type_ref = Module["_mono_wasm_try_unbox_primitive_and_get_type_ref"] = function() {
return (_mono_wasm_try_unbox_primitive_and_get_type_ref = Module["_mono_wasm_try_unbox_primitive_and_get_type_ref"] = Module["asm"]["mono_wasm_try_unbox_primitive_and_get_type_ref"]).apply(null, arguments);
};
var _mono_wasm_array_length = Module["_mono_wasm_array_length"] = function() {
return (_mono_wasm_array_length = Module["_mono_wasm_array_length"] = Module["asm"]["mono_wasm_array_length"]).apply(null, arguments);
};
var _mono_wasm_array_get = Module["_mono_wasm_array_get"] = function() {
return (_mono_wasm_array_get = Module["_mono_wasm_array_get"] = Module["asm"]["mono_wasm_array_get"]).apply(null, arguments);
};
var _mono_wasm_array_get_ref = Module["_mono_wasm_array_get_ref"] = function() {
return (_mono_wasm_array_get_ref = Module["_mono_wasm_array_get_ref"] = Module["asm"]["mono_wasm_array_get_ref"]).apply(null, arguments);
};
var _mono_wasm_obj_array_new_ref = Module["_mono_wasm_obj_array_new_ref"] = function() {
return (_mono_wasm_obj_array_new_ref = Module["_mono_wasm_obj_array_new_ref"] = Module["asm"]["mono_wasm_obj_array_new_ref"]).apply(null, arguments);
};
var _mono_wasm_obj_array_new = Module["_mono_wasm_obj_array_new"] = function() {
return (_mono_wasm_obj_array_new = Module["_mono_wasm_obj_array_new"] = Module["asm"]["mono_wasm_obj_array_new"]).apply(null, arguments);
};
var _mono_wasm_obj_array_set = Module["_mono_wasm_obj_array_set"] = function() {
return (_mono_wasm_obj_array_set = Module["_mono_wasm_obj_array_set"] = Module["asm"]["mono_wasm_obj_array_set"]).apply(null, arguments);
};
var _mono_wasm_obj_array_set_ref = Module["_mono_wasm_obj_array_set_ref"] = function() {
return (_mono_wasm_obj_array_set_ref = Module["_mono_wasm_obj_array_set_ref"] = Module["asm"]["mono_wasm_obj_array_set_ref"]).apply(null, arguments);
};
var _mono_wasm_string_array_new_ref = Module["_mono_wasm_string_array_new_ref"] = function() {
return (_mono_wasm_string_array_new_ref = Module["_mono_wasm_string_array_new_ref"] = Module["asm"]["mono_wasm_string_array_new_ref"]).apply(null, arguments);
};
var _mono_wasm_exec_regression = Module["_mono_wasm_exec_regression"] = function() {
return (_mono_wasm_exec_regression = Module["_mono_wasm_exec_regression"] = Module["asm"]["mono_wasm_exec_regression"]).apply(null, arguments);
};
var _mono_wasm_exit = Module["_mono_wasm_exit"] = function() {
return (_mono_wasm_exit = Module["_mono_wasm_exit"] = Module["asm"]["mono_wasm_exit"]).apply(null, arguments);
};
var _mono_wasm_set_main_args = Module["_mono_wasm_set_main_args"] = function() {
return (_mono_wasm_set_main_args = Module["_mono_wasm_set_main_args"] = Module["asm"]["mono_wasm_set_main_args"]).apply(null, arguments);
};
var _mono_wasm_strdup = Module["_mono_wasm_strdup"] = function() {
return (_mono_wasm_strdup = Module["_mono_wasm_strdup"] = Module["asm"]["mono_wasm_strdup"]).apply(null, arguments);
};
var _mono_wasm_parse_runtime_options = Module["_mono_wasm_parse_runtime_options"] = function() {
return (_mono_wasm_parse_runtime_options = Module["_mono_wasm_parse_runtime_options"] = Module["asm"]["mono_wasm_parse_runtime_options"]).apply(null, arguments);
};
var _mono_wasm_enable_on_demand_gc = Module["_mono_wasm_enable_on_demand_gc"] = function() {
return (_mono_wasm_enable_on_demand_gc = Module["_mono_wasm_enable_on_demand_gc"] = Module["asm"]["mono_wasm_enable_on_demand_gc"]).apply(null, arguments);
};
var _mono_wasm_intern_string_ref = Module["_mono_wasm_intern_string_ref"] = function() {
return (_mono_wasm_intern_string_ref = Module["_mono_wasm_intern_string_ref"] = Module["asm"]["mono_wasm_intern_string_ref"]).apply(null, arguments);
};
var _mono_wasm_string_get_data_ref = Module["_mono_wasm_string_get_data_ref"] = function() {
return (_mono_wasm_string_get_data_ref = Module["_mono_wasm_string_get_data_ref"] = Module["asm"]["mono_wasm_string_get_data_ref"]).apply(null, arguments);
};
var _mono_wasm_string_get_data = Module["_mono_wasm_string_get_data"] = function() {
return (_mono_wasm_string_get_data = Module["_mono_wasm_string_get_data"] = Module["asm"]["mono_wasm_string_get_data"]).apply(null, arguments);
};
var _mono_wasm_class_get_type = Module["_mono_wasm_class_get_type"] = function() {
return (_mono_wasm_class_get_type = Module["_mono_wasm_class_get_type"] = Module["asm"]["mono_wasm_class_get_type"]).apply(null, arguments);
};
var _mono_wasm_type_get_class = Module["_mono_wasm_type_get_class"] = function() {
return (_mono_wasm_type_get_class = Module["_mono_wasm_type_get_class"] = Module["asm"]["mono_wasm_type_get_class"]).apply(null, arguments);
};
var _mono_wasm_get_type_name = Module["_mono_wasm_get_type_name"] = function() {
return (_mono_wasm_get_type_name = Module["_mono_wasm_get_type_name"] = Module["asm"]["mono_wasm_get_type_name"]).apply(null, arguments);
};
var _mono_wasm_get_type_aqn = Module["_mono_wasm_get_type_aqn"] = function() {
return (_mono_wasm_get_type_aqn = Module["_mono_wasm_get_type_aqn"] = Module["asm"]["mono_wasm_get_type_aqn"]).apply(null, arguments);
};
var _mono_wasm_write_managed_pointer_unsafe = Module["_mono_wasm_write_managed_pointer_unsafe"] = function() {
return (_mono_wasm_write_managed_pointer_unsafe = Module["_mono_wasm_write_managed_pointer_unsafe"] = Module["asm"]["mono_wasm_write_managed_pointer_unsafe"]).apply(null, arguments);
};
var _mono_wasm_copy_managed_pointer = Module["_mono_wasm_copy_managed_pointer"] = function() {
return (_mono_wasm_copy_managed_pointer = Module["_mono_wasm_copy_managed_pointer"] = Module["asm"]["mono_wasm_copy_managed_pointer"]).apply(null, arguments);
};
var _mono_wasm_load_profiler_aot = Module["_mono_wasm_load_profiler_aot"] = function() {
return (_mono_wasm_load_profiler_aot = Module["_mono_wasm_load_profiler_aot"] = Module["asm"]["mono_wasm_load_profiler_aot"]).apply(null, arguments);
};
var _mono_wasm_i52_to_f64 = Module["_mono_wasm_i52_to_f64"] = function() {
return (_mono_wasm_i52_to_f64 = Module["_mono_wasm_i52_to_f64"] = Module["asm"]["mono_wasm_i52_to_f64"]).apply(null, arguments);
};
var _mono_wasm_u52_to_f64 = Module["_mono_wasm_u52_to_f64"] = function() {
return (_mono_wasm_u52_to_f64 = Module["_mono_wasm_u52_to_f64"] = Module["asm"]["mono_wasm_u52_to_f64"]).apply(null, arguments);
};
var _mono_wasm_f64_to_u52 = Module["_mono_wasm_f64_to_u52"] = function() {
return (_mono_wasm_f64_to_u52 = Module["_mono_wasm_f64_to_u52"] = Module["asm"]["mono_wasm_f64_to_u52"]).apply(null, arguments);
};
var _mono_wasm_f64_to_i52 = Module["_mono_wasm_f64_to_i52"] = function() {
return (_mono_wasm_f64_to_i52 = Module["_mono_wasm_f64_to_i52"] = Module["asm"]["mono_wasm_f64_to_i52"]).apply(null, arguments);
};
var _mono_wasm_set_is_debugger_attached = Module["_mono_wasm_set_is_debugger_attached"] = function() {
return (_mono_wasm_set_is_debugger_attached = Module["_mono_wasm_set_is_debugger_attached"] = Module["asm"]["mono_wasm_set_is_debugger_attached"]).apply(null, arguments);
};
var _mono_wasm_change_debugger_log_level = Module["_mono_wasm_change_debugger_log_level"] = function() {
return (_mono_wasm_change_debugger_log_level = Module["_mono_wasm_change_debugger_log_level"] = Module["asm"]["mono_wasm_change_debugger_log_level"]).apply(null, arguments);
};
var _mono_wasm_send_dbg_command_with_parms = Module["_mono_wasm_send_dbg_command_with_parms"] = function() {
return (_mono_wasm_send_dbg_command_with_parms = Module["_mono_wasm_send_dbg_command_with_parms"] = Module["asm"]["mono_wasm_send_dbg_command_with_parms"]).apply(null, arguments);
};
var _mono_wasm_send_dbg_command = Module["_mono_wasm_send_dbg_command"] = function() {
return (_mono_wasm_send_dbg_command = Module["_mono_wasm_send_dbg_command"] = Module["asm"]["mono_wasm_send_dbg_command"]).apply(null, arguments);
};
var _mono_wasm_event_pipe_enable = Module["_mono_wasm_event_pipe_enable"] = function() {
return (_mono_wasm_event_pipe_enable = Module["_mono_wasm_event_pipe_enable"] = Module["asm"]["mono_wasm_event_pipe_enable"]).apply(null, arguments);
};
var _mono_wasm_event_pipe_session_start_streaming = Module["_mono_wasm_event_pipe_session_start_streaming"] = function() {
return (_mono_wasm_event_pipe_session_start_streaming = Module["_mono_wasm_event_pipe_session_start_streaming"] = Module["asm"]["mono_wasm_event_pipe_session_start_streaming"]).apply(null, arguments);
};
var _mono_wasm_event_pipe_session_disable = Module["_mono_wasm_event_pipe_session_disable"] = function() {
return (_mono_wasm_event_pipe_session_disable = Module["_mono_wasm_event_pipe_session_disable"] = Module["asm"]["mono_wasm_event_pipe_session_disable"]).apply(null, arguments);
};
var ___errno_location = Module["___errno_location"] = function() {
return (___errno_location = Module["___errno_location"] = Module["asm"]["__errno_location"]).apply(null, arguments);
};
var _ntohs = Module["_ntohs"] = function() {
return (_ntohs = Module["_ntohs"] = Module["asm"]["ntohs"]).apply(null, arguments);
};
var _pthread_self = Module["_pthread_self"] = function() {
return (_pthread_self = Module["_pthread_self"] = Module["asm"]["pthread_self"]).apply(null, arguments);
};
var _mono_background_exec = Module["_mono_background_exec"] = function() {
return (_mono_background_exec = Module["_mono_background_exec"] = Module["asm"]["mono_background_exec"]).apply(null, arguments);
};
var _emscripten_main_browser_thread_id = Module["_emscripten_main_browser_thread_id"] = function() {
return (_emscripten_main_browser_thread_id = Module["_emscripten_main_browser_thread_id"] = Module["asm"]["emscripten_main_browser_thread_id"]).apply(null, arguments);
};
var _htons = Module["_htons"] = function() {
return (_htons = Module["_htons"] = Module["asm"]["htons"]).apply(null, arguments);
};
var _mono_wasm_get_icudt_name = Module["_mono_wasm_get_icudt_name"] = function() {
return (_mono_wasm_get_icudt_name = Module["_mono_wasm_get_icudt_name"] = Module["asm"]["mono_wasm_get_icudt_name"]).apply(null, arguments);
};
var _mono_wasm_load_icu_data = Module["_mono_wasm_load_icu_data"] = function() {
return (_mono_wasm_load_icu_data = Module["_mono_wasm_load_icu_data"] = Module["asm"]["mono_wasm_load_icu_data"]).apply(null, arguments);
};
var _mono_print_method_from_ip = Module["_mono_print_method_from_ip"] = function() {
return (_mono_print_method_from_ip = Module["_mono_print_method_from_ip"] = Module["asm"]["mono_print_method_from_ip"]).apply(null, arguments);
};
var _mono_set_timeout_exec = Module["_mono_set_timeout_exec"] = function() {
return (_mono_set_timeout_exec = Module["_mono_set_timeout_exec"] = Module["asm"]["mono_set_timeout_exec"]).apply(null, arguments);
};
var _memset = Module["_memset"] = function() {
return (_memset = Module["_memset"] = Module["asm"]["memset"]).apply(null, arguments);
};
var __emscripten_tls_init = Module["__emscripten_tls_init"] = function() {
return (__emscripten_tls_init = Module["__emscripten_tls_init"] = Module["asm"]["_emscripten_tls_init"]).apply(null, arguments);
};
var _emscripten_builtin_memalign = Module["_emscripten_builtin_memalign"] = function() {
return (_emscripten_builtin_memalign = Module["_emscripten_builtin_memalign"] = Module["asm"]["emscripten_builtin_memalign"]).apply(null, arguments);
};
var ___dl_seterr = Module["___dl_seterr"] = function() {
return (___dl_seterr = Module["___dl_seterr"] = Module["asm"]["__dl_seterr"]).apply(null, arguments);
};
var __emscripten_thread_init = Module["__emscripten_thread_init"] = function() {
return (__emscripten_thread_init = Module["__emscripten_thread_init"] = Module["asm"]["_emscripten_thread_init"]).apply(null, arguments);
};
var __emscripten_thread_crashed = Module["__emscripten_thread_crashed"] = function() {
return (__emscripten_thread_crashed = Module["__emscripten_thread_crashed"] = Module["asm"]["_emscripten_thread_crashed"]).apply(null, arguments);
};
var _emscripten_main_thread_process_queued_calls = Module["_emscripten_main_thread_process_queued_calls"] = function() {
return (_emscripten_main_thread_process_queued_calls = Module["_emscripten_main_thread_process_queued_calls"] = Module["asm"]["emscripten_main_thread_process_queued_calls"]).apply(null, arguments);
};
var _htonl = Module["_htonl"] = function() {
return (_htonl = Module["_htonl"] = Module["asm"]["htonl"]).apply(null, arguments);
};
var _emscripten_run_in_main_runtime_thread_js = Module["_emscripten_run_in_main_runtime_thread_js"] = function() {
return (_emscripten_run_in_main_runtime_thread_js = Module["_emscripten_run_in_main_runtime_thread_js"] = Module["asm"]["emscripten_run_in_main_runtime_thread_js"]).apply(null, arguments);
};
var _emscripten_dispatch_to_thread_ = Module["_emscripten_dispatch_to_thread_"] = function() {
return (_emscripten_dispatch_to_thread_ = Module["_emscripten_dispatch_to_thread_"] = Module["asm"]["emscripten_dispatch_to_thread_"]).apply(null, arguments);
};
var __emscripten_proxy_execute_task_queue = Module["__emscripten_proxy_execute_task_queue"] = function() {
return (__emscripten_proxy_execute_task_queue = Module["__emscripten_proxy_execute_task_queue"] = Module["asm"]["_emscripten_proxy_execute_task_queue"]).apply(null, arguments);
};
var __emscripten_thread_free_data = Module["__emscripten_thread_free_data"] = function() {
return (__emscripten_thread_free_data = Module["__emscripten_thread_free_data"] = Module["asm"]["_emscripten_thread_free_data"]).apply(null, arguments);
};
var __emscripten_thread_exit = Module["__emscripten_thread_exit"] = function() {
return (__emscripten_thread_exit = Module["__emscripten_thread_exit"] = Module["asm"]["_emscripten_thread_exit"]).apply(null, arguments);
};
var _memalign = Module["_memalign"] = function() {
return (_memalign = Module["_memalign"] = Module["asm"]["memalign"]).apply(null, arguments);
};
var _setThrew = Module["_setThrew"] = function() {
return (_setThrew = Module["_setThrew"] = Module["asm"]["setThrew"]).apply(null, arguments);
};
var _emscripten_stack_set_limits = Module["_emscripten_stack_set_limits"] = function() {
return (_emscripten_stack_set_limits = Module["_emscripten_stack_set_limits"] = Module["asm"]["emscripten_stack_set_limits"]).apply(null, arguments);
};
var stackSave = Module["stackSave"] = function() {
return (stackSave = Module["stackSave"] = Module["asm"]["stackSave"]).apply(null, arguments);
};
var stackRestore = Module["stackRestore"] = function() {
return (stackRestore = Module["stackRestore"] = Module["asm"]["stackRestore"]).apply(null, arguments);
};
var stackAlloc = Module["stackAlloc"] = function() {
return (stackAlloc = Module["stackAlloc"] = Module["asm"]["stackAlloc"]).apply(null, arguments);
};
var ___cxa_can_catch = Module["___cxa_can_catch"] = function() {
return (___cxa_can_catch = Module["___cxa_can_catch"] = Module["asm"]["__cxa_can_catch"]).apply(null, arguments);
};
var ___cxa_is_pointer_type = Module["___cxa_is_pointer_type"] = function() {
return (___cxa_is_pointer_type = Module["___cxa_is_pointer_type"] = Module["asm"]["__cxa_is_pointer_type"]).apply(null, arguments);
};
var dynCall_iiij = Module["dynCall_iiij"] = function() {
return (dynCall_iiij = Module["dynCall_iiij"] = Module["asm"]["dynCall_iiij"]).apply(null, arguments);
};
var dynCall_iijj = Module["dynCall_iijj"] = function() {
return (dynCall_iijj = Module["dynCall_iijj"] = Module["asm"]["dynCall_iijj"]).apply(null, arguments);
};
var dynCall_iij = Module["dynCall_iij"] = function() {
return (dynCall_iij = Module["dynCall_iij"] = Module["asm"]["dynCall_iij"]).apply(null, arguments);
};
var dynCall_j = Module["dynCall_j"] = function() {
return (dynCall_j = Module["dynCall_j"] = Module["asm"]["dynCall_j"]).apply(null, arguments);
};
var dynCall_iijji = Module["dynCall_iijji"] = function() {
return (dynCall_iijji = Module["dynCall_iijji"] = Module["asm"]["dynCall_iijji"]).apply(null, arguments);
};
var dynCall_jiji = Module["dynCall_jiji"] = function() {
return (dynCall_jiji = Module["dynCall_jiji"] = Module["asm"]["dynCall_jiji"]).apply(null, arguments);
};
var dynCall_iiji = Module["dynCall_iiji"] = function() {
return (dynCall_iiji = Module["dynCall_iiji"] = Module["asm"]["dynCall_iiji"]).apply(null, arguments);
};
var dynCall_iijiiij = Module["dynCall_iijiiij"] = function() {
return (dynCall_iijiiij = Module["dynCall_iijiiij"] = Module["asm"]["dynCall_iijiiij"]).apply(null, arguments);
};
var dynCall_iiiij = Module["dynCall_iiiij"] = function() {
return (dynCall_iiiij = Module["dynCall_iiiij"] = Module["asm"]["dynCall_iiiij"]).apply(null, arguments);
};
var dynCall_jiiij = Module["dynCall_jiiij"] = function() {
return (dynCall_jiiij = Module["dynCall_jiiij"] = Module["asm"]["dynCall_jiiij"]).apply(null, arguments);
};
var dynCall_ji = Module["dynCall_ji"] = function() {
return (dynCall_ji = Module["dynCall_ji"] = Module["asm"]["dynCall_ji"]).apply(null, arguments);
};
var dynCall_jiiiiiiiii = Module["dynCall_jiiiiiiiii"] = function() {
return (dynCall_jiiiiiiiii = Module["dynCall_jiiiiiiiii"] = Module["asm"]["dynCall_jiiiiiiiii"]).apply(null, arguments);
};
var dynCall_vj = Module["dynCall_vj"] = function() {
return (dynCall_vj = Module["dynCall_vj"] = Module["asm"]["dynCall_vj"]).apply(null, arguments);
};
var dynCall_iji = Module["dynCall_iji"] = function() {
return (dynCall_iji = Module["dynCall_iji"] = Module["asm"]["dynCall_iji"]).apply(null, arguments);
};
var dynCall_ij = Module["dynCall_ij"] = function() {
return (dynCall_ij = Module["dynCall_ij"] = Module["asm"]["dynCall_ij"]).apply(null, arguments);
};
var dynCall_jj = Module["dynCall_jj"] = function() {
return (dynCall_jj = Module["dynCall_jj"] = Module["asm"]["dynCall_jj"]).apply(null, arguments);
};
var dynCall_iiijiiiii = Module["dynCall_iiijiiiii"] = function() {
return (dynCall_iiijiiiii = Module["dynCall_iiijiiiii"] = Module["asm"]["dynCall_iiijiiiii"]).apply(null, arguments);
};
var dynCall_viiijjii = Module["dynCall_viiijjii"] = function() {
return (dynCall_viiijjii = Module["dynCall_viiijjii"] = Module["asm"]["dynCall_viiijjii"]).apply(null, arguments);
};
var dynCall_iijjiii = Module["dynCall_iijjiii"] = function() {
return (dynCall_iijjiii = Module["dynCall_iijjiii"] = Module["asm"]["dynCall_iijjiii"]).apply(null, arguments);
};
var dynCall_vijjjii = Module["dynCall_vijjjii"] = function() {
return (dynCall_vijjjii = Module["dynCall_vijjjii"] = Module["asm"]["dynCall_vijjjii"]).apply(null, arguments);
};
var dynCall_iijii = Module["dynCall_iijii"] = function() {
return (dynCall_iijii = Module["dynCall_iijii"] = Module["asm"]["dynCall_iijii"]).apply(null, arguments);
};
var dynCall_iijiii = Module["dynCall_iijiii"] = function() {
return (dynCall_iijiii = Module["dynCall_iijiii"] = Module["asm"]["dynCall_iijiii"]).apply(null, arguments);
};
var dynCall_vijiiii = Module["dynCall_vijiiii"] = function() {
return (dynCall_vijiiii = Module["dynCall_vijiiii"] = Module["asm"]["dynCall_vijiiii"]).apply(null, arguments);
};
var dynCall_jij = Module["dynCall_jij"] = function() {
return (dynCall_jij = Module["dynCall_jij"] = Module["asm"]["dynCall_jij"]).apply(null, arguments);
};
var dynCall_vij = Module["dynCall_vij"] = function() {
return (dynCall_vij = Module["dynCall_vij"] = Module["asm"]["dynCall_vij"]).apply(null, arguments);
};
var dynCall_jii = Module["dynCall_jii"] = function() {
return (dynCall_jii = Module["dynCall_jii"] = Module["asm"]["dynCall_jii"]).apply(null, arguments);
};
var dynCall_iijiiii = Module["dynCall_iijiiii"] = function() {
return (dynCall_iijiiii = Module["dynCall_iijiiii"] = Module["asm"]["dynCall_iijiiii"]).apply(null, arguments);
};
var dynCall_jd = Module["dynCall_jd"] = function() {
return (dynCall_jd = Module["dynCall_jd"] = Module["asm"]["dynCall_jd"]).apply(null, arguments);
};
var dynCall_jf = Module["dynCall_jf"] = function() {
return (dynCall_jf = Module["dynCall_jf"] = Module["asm"]["dynCall_jf"]).apply(null, arguments);
};
var dynCall_iiijiiii = Module["dynCall_iiijiiii"] = function() {
return (dynCall_iiijiiii = Module["dynCall_iiijiiii"] = Module["asm"]["dynCall_iiijiiii"]).apply(null, arguments);
};
var dynCall_jiiiii = Module["dynCall_jiiiii"] = function() {
return (dynCall_jiiiii = Module["dynCall_jiiiii"] = Module["asm"]["dynCall_jiiiii"]).apply(null, arguments);
};
var dynCall_viij = Module["dynCall_viij"] = function() {
return (dynCall_viij = Module["dynCall_viij"] = Module["asm"]["dynCall_viij"]).apply(null, arguments);
};
var dynCall_jijj = Module["dynCall_jijj"] = function() {
return (dynCall_jijj = Module["dynCall_jijj"] = Module["asm"]["dynCall_jijj"]).apply(null, arguments);
};
function invoke_vi(index, a1) {
var sp = stackSave();
try {
getWasmTableEntry(index)(a1);
} catch (e) {
stackRestore(sp);
if (e !== e + 0) throw e;
_setThrew(1, 0);
}
}
Module["ccall"] = ccall;
Module["cwrap"] = cwrap;
Module["UTF8ArrayToString"] = UTF8ArrayToString;
Module["UTF8ToString"] = UTF8ToString;
Module["addRunDependency"] = addRunDependency;
Module["removeRunDependency"] = removeRunDependency;
Module["FS_createPath"] = FS.createPath;
Module["FS_createDataFile"] = FS.createDataFile;
Module["FS_createPreloadedFile"] = FS.createPreloadedFile;
Module["FS_createLazyFile"] = FS.createLazyFile;
Module["FS_createDevice"] = FS.createDevice;
Module["FS_unlink"] = FS.unlink;
Module["print"] = out;
Module["keepRuntimeAlive"] = keepRuntimeAlive;
Module["wasmMemory"] = wasmMemory;
Module["ExitStatus"] = ExitStatus;
Module["setValue"] = setValue;
Module["getValue"] = getValue;
Module["FS"] = FS;
Module["PThread"] = PThread;
var calledRun;
function ExitStatus(status) {
this.name = "ExitStatus";
this.message = "Program terminated with exit(" + status + ")";
this.status = status;
}
var calledMain = false;
dependenciesFulfilled = function runCaller() {
if (!calledRun) run();
if (!calledRun) dependenciesFulfilled = runCaller;
};
function run(args) {
args = args || arguments_;
if (runDependencies > 0) {
return;
}
if (ENVIRONMENT_IS_PTHREAD) {
readyPromiseResolve(Module);
initRuntime();
postMessage({
"cmd": "loaded"
});
return;
}
preRun();
if (runDependencies > 0) {
return;
}
function doRun() {
if (calledRun) return;
calledRun = true;
Module["calledRun"] = true;
if (ABORT) return;
initRuntime();
readyPromiseResolve(Module);
if (Module["onRuntimeInitialized"]) Module["onRuntimeInitialized"]();
postRun();
}
if (Module["setStatus"]) {
Module["setStatus"]("Running...");
setTimeout(function() {
setTimeout(function() {
Module["setStatus"]("");
}, 1);
doRun();
}, 1);
} else {
doRun();
}
}
Module["run"] = run;
function exit(status, implicit) {
EXITSTATUS = status;
if (!implicit) {
if (ENVIRONMENT_IS_PTHREAD) {
exitOnMainThread(status);
throw "unwind";
} else {}
}
procExit(status);
}
function procExit(code) {
EXITSTATUS = code;
if (!keepRuntimeAlive()) {
PThread.terminateAllThreads();
if (Module["onExit"]) Module["onExit"](code);
ABORT = true;
}
quit_(code, new ExitStatus(code));
}
if (Module["preInit"]) {
if (typeof Module["preInit"] == "function") Module["preInit"] = [ Module["preInit"] ];
while (Module["preInit"].length > 0) {
Module["preInit"].pop()();
}
}
run();
createDotnetRuntime.ready = createDotnetRuntime.ready.then(() => {
return __dotnet_exportedAPI;
});
return createDotnetRuntime.ready
}
);
})();
export default createDotnetRuntime;
/**
* @license
* Copyright 2015 The Emscripten Authors
* SPDX-License-Identifier: MIT
*/
// Pthread Web Worker startup routine:
// This is the entry point file that is loaded first by each Web Worker
// that executes pthreads on the Emscripten application.
'use strict';
var Module = {};
// Node.js support
var ENVIRONMENT_IS_NODE = typeof process == 'object' && typeof process.versions == 'object' && typeof process.versions.node == 'string';
if (ENVIRONMENT_IS_NODE) {
// Create as web-worker-like an environment as we can.
var nodeWorkerThreads = require('worker_threads');
var parentPort = nodeWorkerThreads.parentPort;
parentPort.on('message', function(data) {
onmessage({ data: data });
});
var fs = require('fs');
Object.assign(global, {
self: global,
require: require,
Module: Module,
location: {
href: __filename
},
Worker: nodeWorkerThreads.Worker,
importScripts: function(f) {
(0, eval)(fs.readFileSync(f, 'utf8'));
},
postMessage: function(msg) {
parentPort.postMessage(msg);
},
performance: global.performance || {
now: function() {
return Date.now();
}
},
});
}
// Thread-local guard variable for one-time init of the JS state
var initializedJS = false;
// Proxying queues that were notified before the thread started and need to be
// executed as part of startup.
var pendingNotifiedProxyingQueues = [];
function threadPrintErr() {
var text = Array.prototype.slice.call(arguments).join(' ');
// See https://github.com/emscripten-core/emscripten/issues/14804
if (ENVIRONMENT_IS_NODE) {
fs.writeSync(2, text + '\n');
return;
}
console.error(text);
}
function threadAlert() {
var text = Array.prototype.slice.call(arguments).join(' ');
postMessage({cmd: 'alert', text: text, threadId: Module['_pthread_self']()});
}
var err = threadPrintErr;
self.alert = threadAlert;
Module['instantiateWasm'] = (info, receiveInstance) => {
// Instantiate from the module posted from the main thread.
// We can just use sync instantiation in the worker.
var instance = new WebAssembly.Instance(Module['wasmModule'], info);
// TODO: Due to Closure regression https://github.com/google/closure-compiler/issues/3193,
// the above line no longer optimizes out down to the following line.
// When the regression is fixed, we can remove this if/else.
receiveInstance(instance);
// We don't need the module anymore; new threads will be spawned from the main thread.
Module['wasmModule'] = null;
return instance.exports;
}
self.onmessage = (e) => {
try {
if (e.data.cmd === 'load') { // Preload command that is called once per worker to parse and load the Emscripten code.
// Module and memory were sent from main thread
Module['wasmModule'] = e.data.wasmModule;
Module['wasmMemory'] = e.data.wasmMemory;
Module['buffer'] = Module['wasmMemory'].buffer;
Module['ENVIRONMENT_IS_PTHREAD'] = true;
(e.data.urlOrBlob ? import(e.data.urlOrBlob) : import('./dotnet.js')).then(function(exports) {
return exports.default(Module);
}).then(function(instance) {
Module = instance;
});
} else if (e.data.cmd === 'run') {
// This worker was idle, and now should start executing its pthread entry
// point.
// performance.now() is specced to return a wallclock time in msecs since
// that Web Worker/main thread launched. However for pthreads this can
// cause subtle problems in emscripten_get_now() as this essentially
// would measure time from pthread_create(), meaning that the clocks
// between each threads would be wildly out of sync. Therefore sync all
// pthreads to the clock on the main browser thread, so that different
// threads see a somewhat coherent clock across each of them
// (+/- 0.1msecs in testing).
Module['__performance_now_clock_drift'] = performance.now() - e.data.time;
// Pass the thread address inside the asm.js scope to store it for fast access that avoids the need for a FFI out.
Module['__emscripten_thread_init'](e.data.threadInfoStruct, /*isMainBrowserThread=*/0, /*isMainRuntimeThread=*/0, /*canBlock=*/1);
// Also call inside JS module to set up the stack frame for this pthread in JS module scope
Module['establishStackSpace']();
Module['PThread'].receiveObjectTransfer(e.data);
Module['PThread'].threadInitTLS();
if (!initializedJS) {
// Execute any proxied work that came in before the thread was
// initialized. Only do this once because it is only possible for
// proxying notifications to arrive before thread initialization on
// fresh workers.
pendingNotifiedProxyingQueues.forEach(queue => {
Module['executeNotifiedProxyingQueue'](queue);
});
pendingNotifiedProxyingQueues = [];
initializedJS = true;
}
try {
// pthread entry points are always of signature 'void *ThreadMain(void *arg)'
// Native codebases sometimes spawn threads with other thread entry point signatures,
// such as void ThreadMain(void *arg), void *ThreadMain(), or void ThreadMain().
// That is not acceptable per C/C++ specification, but x86 compiler ABI extensions
// enable that to work. If you find the following line to crash, either change the signature
// to "proper" void *ThreadMain(void *arg) form, or try linking with the Emscripten linker
// flag -sEMULATE_FUNCTION_POINTER_CASTS to add in emulation for this x86 ABI extension.
var result = Module['invokeEntryPoint'](e.data.start_routine, e.data.arg);
if (Module['keepRuntimeAlive']()) {
Module['PThread'].setExitStatus(result);
} else {
Module['__emscripten_thread_exit'](result);
}
} catch(ex) {
if (ex != 'unwind') {
// ExitStatus not present in MINIMAL_RUNTIME
if (ex instanceof Module['ExitStatus']) {
if (Module['keepRuntimeAlive']()) {
} else {
Module['__emscripten_thread_exit'](ex.status);
}
}
else
{
// The pthread "crashed". Do not call `_emscripten_thread_exit` (which
// would make this thread joinable. Instead, re-throw the exception
// and let the top level handler propagate it back to the main thread.
throw ex;
}
}
}
} else if (e.data.cmd === 'cancel') { // Main thread is asking for a pthread_cancel() on this thread.
if (Module['_pthread_self']()) {
Module['__emscripten_thread_exit'](-1/*PTHREAD_CANCELED*/);
}
} else if (e.data.target === 'setimmediate') {
// no-op
} else if (e.data.cmd === 'processProxyingQueue') {
if (initializedJS) {
Module['executeNotifiedProxyingQueue'](e.data.queue);
} else {
// Defer executing this queue until the runtime is initialized.
pendingNotifiedProxyingQueues.push(e.data.queue);
}
} else {
err('worker.js received unknown command ' + e.data.cmd);
err(e.data);
}
} catch(ex) {
err('worker.js onmessage() captured an uncaught exception: ' + ex);
if (ex && ex.stack) err(ex.stack);
if (Module['__emscripten_thread_crashed']) {
Module['__emscripten_thread_crashed']();
}
throw ex;
}
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment