diff --git a/src/mono/wasm/runtime/cjs/dotnet.cjs.extpost.js b/src/mono/wasm/runtime/cjs/dotnet.cjs.extpost.js index a1867520b68579..51e9ac0717e812 100644 --- a/src/mono/wasm/runtime/cjs/dotnet.cjs.extpost.js +++ b/src/mono/wasm/runtime/cjs/dotnet.cjs.extpost.js @@ -1,3 +1,4 @@ +var require = require || undefined; // if loaded into global namespace and configured with global Module, we will self start in compatibility mode let ENVIRONMENT_IS_GLOBAL = typeof globalThis.Module === "object" && globalThis.__dotnet_runtime === __dotnet_runtime; if (ENVIRONMENT_IS_GLOBAL) { diff --git a/src/mono/wasm/runtime/cjs/dotnet.cjs.lib.js b/src/mono/wasm/runtime/cjs/dotnet.cjs.lib.js index 4dfe69ccac8553..636d97487fc79a 100644 --- a/src/mono/wasm/runtime/cjs/dotnet.cjs.lib.js +++ b/src/mono/wasm/runtime/cjs/dotnet.cjs.lib.js @@ -6,22 +6,23 @@ const DotnetSupportLib = { $DOTNET: {}, - // this line will be placed early on emscripten runtime creation, passing import and export objects into __dotnet_runtime IFFE + // these lines will be placed early on emscripten runtime creation, passing import and export objects into __dotnet_runtime IFFE $DOTNET__postset: ` - let __dotnet_replacements = {scriptDirectory, readAsync, fetch: globalThis.fetch}; - let __dotnet_exportedAPI = __dotnet_runtime.__initializeImportsAndExports( - { isGlobal:ENVIRONMENT_IS_GLOBAL, isNode:ENVIRONMENT_IS_NODE, isShell:ENVIRONMENT_IS_SHELL, isWeb:ENVIRONMENT_IS_WEB, locateFile }, - { mono:MONO, binding:BINDING, internal:INTERNAL, module:Module }, - __dotnet_replacements); - - // here we replace things which are not exposed in another way - scriptDirectory = __dotnet_replacements.scriptDirectory; - readAsync = __dotnet_replacements.readAsync; - var fetch = __dotnet_replacements.fetch; - if (ENVIRONMENT_IS_NODE) { - __dirname = __dotnet_replacements.scriptDirectory; - } - `, +let __dotnet_replacements = {scriptDirectory, readAsync, fetch: globalThis.fetch, require}; +let __dotnet_exportedAPI = __dotnet_runtime.__initializeImportsAndExports( + { isES6:false, isGlobal:ENVIRONMENT_IS_GLOBAL, isNode:ENVIRONMENT_IS_NODE, isShell:ENVIRONMENT_IS_SHELL, isWeb:ENVIRONMENT_IS_WEB, locateFile, quit_ }, + { mono:MONO, binding:BINDING, internal:INTERNAL, module:Module }, + __dotnet_replacements); + +// here we replace things which are not exposed in another way +scriptDirectory = __dotnet_replacements.scriptDirectory; +readAsync = __dotnet_replacements.readAsync; +var fetch = __dotnet_replacements.fetch; +if (ENVIRONMENT_IS_NODE) { + __dirname = __dotnet_replacements.scriptDirectory; + require = __dotnet_replacements.require; +} +`, }; // the methods would be visible to EMCC linker diff --git a/src/mono/wasm/runtime/cjs/dotnet.cjs.pre.js b/src/mono/wasm/runtime/cjs/dotnet.cjs.pre.js index 6b55ff1360bee7..2479c610416958 100644 --- a/src/mono/wasm/runtime/cjs/dotnet.cjs.pre.js +++ b/src/mono/wasm/runtime/cjs/dotnet.cjs.pre.js @@ -23,4 +23,3 @@ else if (typeof createDotnetRuntime === "function") { else { throw new Error("MONO_WASM: Can't locate global Module object or moduleFactory callback of createDotnetRuntime function.") } -let require = (name) => { return Module.imports.require(name) }; \ No newline at end of file diff --git a/src/mono/wasm/runtime/es6/dotnet.es6.lib.js b/src/mono/wasm/runtime/es6/dotnet.es6.lib.js index 2f94047ddd0ea1..fe2b969606179a 100644 --- a/src/mono/wasm/runtime/es6/dotnet.es6.lib.js +++ b/src/mono/wasm/runtime/es6/dotnet.es6.lib.js @@ -8,44 +8,45 @@ const DotnetSupportLib = { $DOTNET: {}, // this line will be placed early on emscripten runtime creation, passing import and export objects into __dotnet_runtime IFFE $DOTNET__postset: ` - let __dotnet_replacements = {scriptDirectory, readAsync, fetch: globalThis.fetch}; - let __dotnet_exportedAPI = __dotnet_runtime.__initializeImportsAndExports( - { isGlobal:false, isNode:ENVIRONMENT_IS_NODE, isShell:ENVIRONMENT_IS_SHELL, isWeb:ENVIRONMENT_IS_WEB, locateFile }, - { mono:MONO, binding:BINDING, internal:INTERNAL, module:Module }, - __dotnet_replacements); - - // here we replace things which are not exposed in another way - scriptDirectory = __dotnet_replacements.scriptDirectory; - readAsync = __dotnet_replacements.readAsync; - var fetch = __dotnet_replacements.fetch; +let __dotnet_replacements = {scriptDirectory, readAsync, fetch: globalThis.fetch, require}; +let __dotnet_exportedAPI = __dotnet_runtime.__initializeImportsAndExports( + { isES6:true, isGlobal:false, isNode:ENVIRONMENT_IS_NODE, isShell:ENVIRONMENT_IS_SHELL, isWeb:ENVIRONMENT_IS_WEB, locateFile, quit_ }, + { mono:MONO, binding:BINDING, internal:INTERNAL, module:Module }, + __dotnet_replacements); - // here we replace things which are broken on NodeJS for ES6 - if (ENVIRONMENT_IS_NODE) { - __dirname = __dotnet_replacements.scriptDirectory; - getBinaryPromise = async () => { - if (!wasmBinary) { - try { - if (typeof fetch === 'function' && !isFileURI(wasmBinaryFile)) { - const response = await fetch(wasmBinaryFile, { credentials: 'same-origin' }); - if (!response['ok']) { - throw "failed to load wasm binary file at '" + wasmBinaryFile + "'"; - } - return response['arrayBuffer'](); - } - else if (readAsync) { - return await new Promise(function (resolve, reject) { - readAsync(wasmBinaryFile, function (response) { resolve(new Uint8Array(/** @type{!ArrayBuffer} */(response))) }, reject) - }); +// here we replace things which are not exposed in another way +scriptDirectory = __dotnet_replacements.scriptDirectory; +readAsync = __dotnet_replacements.readAsync; +var fetch = __dotnet_replacements.fetch; + +// here we replace things which are broken on NodeJS for ES6 +if (ENVIRONMENT_IS_NODE) { + __dirname = __dotnet_replacements.scriptDirectory; + require = __dotnet_replacements.require; + getBinaryPromise = async () => { + if (!wasmBinary) { + try { + if (typeof fetch === 'function' && !isFileURI(wasmBinaryFile)) { + const response = await fetch(wasmBinaryFile, { credentials: 'same-origin' }); + if (!response['ok']) { + throw "failed to load wasm binary file at '" + wasmBinaryFile + "'"; } - + return response['arrayBuffer'](); } - catch (err) { - return getBinary(wasmBinaryFile); + else if (readAsync) { + return await new Promise(function (resolve, reject) { + readAsync(wasmBinaryFile, function (response) { resolve(new Uint8Array(/** @type{!ArrayBuffer} */(response))) }, reject) + }); } + + } + catch (err) { + return getBinary(wasmBinaryFile); } - return getBinary(wasmBinaryFile); } - }`, + return getBinary(wasmBinaryFile); + } +}`, }; // the methods would be visible to EMCC linker diff --git a/src/mono/wasm/runtime/es6/dotnet.es6.pre.js b/src/mono/wasm/runtime/es6/dotnet.es6.pre.js index b9b456f88e4e54..69d41d5a06343b 100644 --- a/src/mono/wasm/runtime/es6/dotnet.es6.pre.js +++ b/src/mono/wasm/runtime/es6/dotnet.es6.pre.js @@ -17,5 +17,5 @@ else if (typeof createDotnetRuntime === "object") { else { throw new Error("MONO_WASM: Can't use moduleFactory callback of createDotnetRuntime function.") } -let require = (name) => { return Module.imports.require(name) }; -var __dirname = ''; \ No newline at end of file +var require = require || undefined; +var __dirname = __dirname || ''; \ No newline at end of file diff --git a/src/mono/wasm/runtime/exports.ts b/src/mono/wasm/runtime/exports.ts index 911d0382afa049..783360dec4db98 100644 --- a/src/mono/wasm/runtime/exports.ts +++ b/src/mono/wasm/runtime/exports.ts @@ -134,9 +134,9 @@ let exportedAPI: DotnetPublicAPI; // it exports methods to global objects MONO, BINDING and Module in backward compatible way // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types function initializeImportsAndExports( - imports: { isGlobal: boolean, isNode: boolean, isShell: boolean, isWeb: boolean, locateFile: Function }, + imports: { isES6: boolean, isGlobal: boolean, isNode: boolean, isShell: boolean, isWeb: boolean, locateFile: Function, quit_: Function }, exports: { mono: any, binding: any, internal: any, module: any }, - replacements: { scriptDirectory: any, fetch: any, readAsync: any }, + replacements: { scriptDirectory: any, fetch: any, readAsync: any, require: any }, ): DotnetPublicAPI { const module = exports.module as DotnetModule; const globalThisAny = globalThis as any; @@ -184,13 +184,14 @@ function initializeImportsAndExports( } module.imports = module.imports || {}; if (!module.imports.require) { - module.imports.require = globalThis.require; - } - if (!module.imports.require) { + const originalRequire = replacements.require; module.imports.require = (name) => { const resolve = (module.imports)[name]; + if (!resolve && originalRequire) { + return originalRequire(name); + } if (!resolve) - throw new Error(`Please provide Module.imports.${name}`); + throw new Error(`Please provide Module.imports.${name} or Module.imports.require`); return resolve; }; } @@ -206,7 +207,11 @@ function initializeImportsAndExports( } replacements.fetch = runtimeHelpers.fetch; replacements.readAsync = readAsync_like; + replacements.require = module.imports.require; + if (typeof module.disableDotnet6Compatibility === "undefined") { + module.disableDotnet6Compatibility = imports.isES6; + } // here we expose objects global namespace for tests and backward compatibility if (imports.isGlobal || !module.disableDotnet6Compatibility) { Object.assign(module, exportedAPI); diff --git a/src/mono/wasm/runtime/imports.ts b/src/mono/wasm/runtime/imports.ts index 7ebe3a5c09bb02..ecd5916b37c262 100644 --- a/src/mono/wasm/runtime/imports.ts +++ b/src/mono/wasm/runtime/imports.ts @@ -19,10 +19,11 @@ export let ENVIRONMENT_IS_NODE: boolean; export let ENVIRONMENT_IS_SHELL: boolean; export let ENVIRONMENT_IS_WEB: boolean; export let locateFile: Function; +export let quit: Function; // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types export function setImportsAndExports( - imports: { isGlobal: boolean, isNode: boolean, isShell: boolean, isWeb: boolean, locateFile: Function }, + imports: { isGlobal: boolean, isNode: boolean, isShell: boolean, isWeb: boolean, locateFile: Function, quit_: Function }, exports: { mono: any, binding: any, internal: any, module: any }, ): void { MONO = exports.mono; @@ -34,6 +35,7 @@ export function setImportsAndExports( ENVIRONMENT_IS_SHELL = imports.isShell; ENVIRONMENT_IS_WEB = imports.isWeb; locateFile = imports.locateFile; + quit = imports.quit_; } let monoConfig: MonoConfig; diff --git a/src/mono/wasm/runtime/run.ts b/src/mono/wasm/runtime/run.ts index 738873e360ffff..90185fbb00c6fa 100644 --- a/src/mono/wasm/runtime/run.ts +++ b/src/mono/wasm/runtime/run.ts @@ -1,4 +1,4 @@ -import { Module } from "./imports"; +import { Module, quit } from "./imports"; import { mono_call_assembly_entry_point } from "./method-calls"; import { mono_wasm_set_main_args, runtime_is_initialized_reject } from "./startup"; @@ -30,11 +30,5 @@ function set_exit_code(exit_code: number, reason?: any) { Module.printErr(reason.stack); } } - const globalThisAny: any = globalThis; - if (typeof globalThisAny.exit === "function") { - globalThisAny.exit(exit_code); - } - else if (typeof globalThisAny.quit === "function") { - globalThisAny.quit(exit_code); - } + quit(exit_code, reason); }