From b78c830d5aa5449a1dd696973348be9957cb26e6 Mon Sep 17 00:00:00 2001 From: Daniel-Genkin Date: Tue, 15 Jun 2021 10:44:32 -0400 Subject: [PATCH 01/17] Did some cleanup --- src/mono/wasm/runtime-test.js | 239 +++++++++++++++++++--------------- 1 file changed, 136 insertions(+), 103 deletions(-) diff --git a/src/mono/wasm/runtime-test.js b/src/mono/wasm/runtime-test.js index 74aa1083c033d..174f488a67e38 100644 --- a/src/mono/wasm/runtime-test.js +++ b/src/mono/wasm/runtime-test.js @@ -4,7 +4,8 @@ // //glue code to deal with the differences between chrome, ch, d8, jsc and sm. -var is_browser = typeof window != "undefined"; +const is_browser = typeof window != "undefined"; +const is_node = !is_browser && typeof process != 'undefined'; // if the engine doesn't provide a console if (typeof (console) === "undefined") { @@ -18,7 +19,7 @@ globalThis.testConsole = console; function proxyMethod (prefix, func, asJson) { return function() { - var args = [...arguments]; + let args = [...arguments]; if (asJson) { func (JSON.stringify({ method: prefix, @@ -82,7 +83,7 @@ if (typeof crypto === 'undefined') { } } -if (typeof performance == 'undefined') { +if (typeof performance === 'undefined') { // performance.now() is used by emscripten and doesn't work in JSC var performance = { now: function () { @@ -91,29 +92,108 @@ if (typeof performance == 'undefined') { } } +let testArguments = []; try { - if (typeof arguments == "undefined") - arguments = WScript.Arguments; - load = WScript.LoadScriptFile; - read = WScript.LoadBinaryFile; -} catch (e) { -} + if (typeof arguments === "undefined") { + if (is_node) + testArguments = process.argv.slice (2); -try { - if (typeof arguments == "undefined") { if (typeof scriptArgs !== "undefined") - arguments = scriptArgs; + testArguments = scriptArgs; + + else if (typeof WScript !== "undefined" && WScript.Arguments) + testArguments = WScript.Arguments; + } else{ + testArguments = arguments; } } catch (e) { + console.err(e) } -if (arguments === undefined) - arguments = []; +if (is_node) { + var { performance, PerformanceObserver } = require("perf_hooks"); +} + +const IOHandler = { + load: null, + read: null, + + init: function() { + // load: function that loads and executes a script + if (!globalThis.load){ + if (typeof WScript !== "undefined"){ // Chakra + IOHandler.load = WScript.LoadScriptFile; + + } else if (is_node) { // NodeJS + const fs = require ('fs'); + IOHandler.load = function (file) { + eval (fs.readFileSync(file).toString()); + }; + } else if (is_browser) { // vanila JS in browser + IOHandler.load = function (file) { + const script = document.createElement ("script"); + script.src = file; + document.head.appendChild (script); + } + } + } else { + IOHandler.load = load; // shells (v8, JavaScriptCore, Spidermonkey) + } -//end of all the nice shell glue code. + // read: function that just reads a file into a variable + if (!globalThis.read){ + if (typeof WScript !== "undefined"){ + IOHandler.read = WScript.LoadBinaryFile; // Chakra + + } else if (is_node) { // NodeJS + const fs = require ('fs'); + IOHandler.read = function (path) { + return fs.readFileSync(path); + }; + } else if (is_browser) { // vanila JS in browser + // TODO + } + } else { + IOHandler.read = read; // shells (v8, JavaScriptCore, Spidermonkey) + } + }, + + writeContentToFile: function(content, path) { + const stream = FS.open(path, 'w+'); + FS.write(stream, content, 0, content.length, 0); + FS.close(stream); + }, + + fetch: function(asset, params) { + if (is_node || is_browser) { + return fetch (asset, params); + } else { + return new Promise ((resolve, reject) => { + let bytes = null, error = null; + try { + bytes = read (asset, 'binary'); + } catch (exc) { + error = exc; + } + const response = { ok: (bytes && !error), url: asset, + arrayBuffer: function () { + return new Promise ((resolve2, reject2) => { + if (error) + reject2 (error); + else + resolve2 (new Uint8Array (bytes)); + } + )} + } + resolve (response); + }) + } + } +}; +IOHandler.init(); +// end of all the nice shell glue code. // set up a global variable to be accessed in App.init -var testArguments = arguments; function test_exit (exit_code) { if (is_browser) { @@ -144,67 +224,47 @@ function inspect_object (o) { } // Preprocess arguments -var args = testArguments; console.info("Arguments: " + testArguments); -profilers = []; -setenv = {}; -runtime_args = []; -enable_gc = true; -enable_zoneinfo = false; -working_dir='/'; -while (args !== undefined && args.length > 0) { - if (args [0].startsWith ("--profile=")) { - var arg = args [0].substring ("--profile=".length); +let profilers = []; +let setenv = {}; +let runtime_args = []; +let enable_gc = true; +let enable_zoneinfo = false; +let working_dir='/'; +while (testArguments !== undefined && testArguments.length > 0) { + if (testArguments [0].startsWith ("--profile=")) { + var arg = testArguments [0].substring ("--profile=".length); profilers.push (arg); - args = args.slice (1); - } else if (args [0].startsWith ("--setenv=")) { - var arg = args [0].substring ("--setenv=".length); + testArguments = testArguments.slice (1); + } else if (testArguments [0].startsWith ("--setenv=")) { + var arg = testArguments [0].substring ("--setenv=".length); var parts = arg.split ('='); if (parts.length != 2) - fail_exec ("Error: malformed argument: '" + args [0]); + fail_exec ("Error: malformed argument: '" + testArguments [0]); setenv [parts [0]] = parts [1]; - args = args.slice (1); - } else if (args [0].startsWith ("--runtime-arg=")) { - var arg = args [0].substring ("--runtime-arg=".length); - runtime_args.push (arg); - args = args.slice (1); - } else if (args [0] == "--disable-on-demand-gc") { + testArguments = testArguments.slice (1); + } else if (testArguments [0].startsWith ("--runtime-arg=")) { + var arg = testArguments [0].substring ("--runtime-arg=".length); + runtime_testArguments.push (arg); + testArguments = testArguments.slice (1); + } else if (testArguments [0] == "--disable-on-demand-gc") { enable_gc = false; - args = args.slice (1); - } else if (args [0].startsWith ("--working-dir=")) { - var arg = args [0].substring ("--working-dir=".length); + testArguments = testArguments.slice (1); + } else if (testArguments [0].startsWith ("--working-dir=")) { + var arg = testArguments [0].substring ("--working-dir=".length); working_dir = arg; - args = args.slice (1); + testArguments = testArguments.slice (1); } else { break; } } -testArguments = args; // cheap way to let the testing infrastructure know we're running in a browser context (or not) setenv["IsBrowserDomSupported"] = is_browser.toString().toLowerCase(); -function writeContentToFile(content, path) -{ - var stream = FS.open(path, 'w+'); - FS.write(stream, content, 0, content.length, 0); - FS.close(stream); -} - -function loadScript (url) -{ - if (is_browser) { - var script = document.createElement ("script"); - script.src = url; - document.head.appendChild (script); - } else { - load (url); - } -} - -loadScript ("mono-config.js"); +IOHandler.load ("mono-config.js"); var Module = { mainScriptUrlOrBlob: "dotnet.js", @@ -247,44 +307,16 @@ var Module = { /* var content = new Uint8Array (read (asset, 'binary')); var path = asset.substr(config.deploy_prefix.length); - writeContentToFile(content, path); + IOHandler.writeContentToFile(content, path); */ - - if (typeof window != 'undefined') { - return fetch (asset, { credentials: 'same-origin' }); - } else { - // The default mono_load_runtime_and_bcl defaults to using - // fetch to load the assets. It also provides a way to set a - // fetch promise callback. - // Here we wrap the file read in a promise and fake a fetch response - // structure. - return new Promise ((resolve, reject) => { - var bytes = null, error = null; - try { - bytes = read (asset, 'binary'); - } catch (exc) { - error = exc; - } - var response = { ok: (bytes && !error), url: asset, - arrayBuffer: function () { - return new Promise ((resolve2, reject2) => { - if (error) - reject2 (error); - else - resolve2 (new Uint8Array (bytes)); - } - )} - } - resolve (response); - }) - } + return IOHandler.fetch (asset, { credentials: 'same-origin' }); }; MONO.mono_load_runtime_and_bcl_args (config); }, }; -loadScript ("dotnet.js"); +IOHandler.load ("dotnet.js"); const IGNORE_PARAM_COUNT = -1; @@ -303,17 +335,17 @@ var App = { init (""); } - if (args.length == 0) { + if (testArguments.length == 0) { fail_exec ("Missing required --run argument"); return; } - if (args[0] == "--regression") { + if (testArguments[0] == "--regression") { var exec_regression = Module.cwrap ('mono_wasm_exec_regression', 'number', ['number', 'string']) var res = 0; try { - res = exec_regression (10, args[1]); + res = exec_regression (10, testArguments[1]); Module.print ("REGRESSION RESULT: " + res); } catch (e) { Module.print ("ABORT: " + e); @@ -330,23 +362,23 @@ var App = { if (runtime_args.length > 0) MONO.mono_wasm_set_runtime_options (runtime_args); - if (args[0] == "--run") { + if (testArguments[0] == "--run") { // Run an exe - if (args.length == 1) { + if (testArguments.length == 1) { fail_exec ("Error: Missing main executable argument."); return; } - main_assembly_name = args[1]; - var app_args = args.slice (2); + main_assembly_name = testArguments[1]; + var app_args = testArguments.slice (2); - var main_argc = args.length - 2 + 1; + var main_argc = testArguments.length - 2 + 1; var main_argv = Module._malloc (main_argc * 4); aindex = 0; - Module.setValue (main_argv + (aindex * 4), wasm_strdup (args [1]), "i32") + Module.setValue (main_argv + (aindex * 4), wasm_strdup (testArguments [1]), "i32") aindex += 1; - for (var i = 2; i < args.length; ++i) { - Module.setValue (main_argv + (aindex * 4), wasm_strdup (args [i]), "i32"); + for (var i = 2; i < testArguments.length; ++i) { + Module.setValue (main_argv + (aindex * 4), wasm_strdup (testArguments [i]), "i32"); aindex += 1; } wasm_set_main_args (main_argc, main_argv); @@ -368,10 +400,11 @@ var App = { } } else { - fail_exec ("Unhandled argument: " + args [0]); + fail_exec ("Unhandled argument: " + testArguments [0]); } }, call_test_method: function (method_name, args, signature) { + // note: arguments here is the array of arguments passsed to this function if ((arguments.length > 2) && (typeof (signature) !== "string")) throw new Error("Invalid number of arguments for call_test_method"); From 644d1657e791312297f9205c8a50abe211770315 Mon Sep 17 00:00:00 2001 From: Daniel-Genkin Date: Tue, 15 Jun 2021 12:55:11 -0400 Subject: [PATCH 02/17] faked loading async while supporting actual async loading --- src/mono/wasm/runtime-test.js | 38 ++++++++++++++++++++--------------- 1 file changed, 22 insertions(+), 16 deletions(-) diff --git a/src/mono/wasm/runtime-test.js b/src/mono/wasm/runtime-test.js index 174f488a67e38..f01d119717245 100644 --- a/src/mono/wasm/runtime-test.js +++ b/src/mono/wasm/runtime-test.js @@ -120,42 +120,42 @@ const IOHandler = { init: function() { // load: function that loads and executes a script - if (!globalThis.load){ + let loadFunc = globalThis.load; // shells (v8, JavaScriptCore, Spidermonkey) + if (!loadFunc){ if (typeof WScript !== "undefined"){ // Chakra - IOHandler.load = WScript.LoadScriptFile; + loadFunc = WScript.LoadScriptFile; } else if (is_node) { // NodeJS const fs = require ('fs'); - IOHandler.load = function (file) { + loadFunc = function (file) { eval (fs.readFileSync(file).toString()); }; } else if (is_browser) { // vanila JS in browser - IOHandler.load = function (file) { + loadFunc = function (file) { const script = document.createElement ("script"); script.src = file; document.head.appendChild (script); } } - } else { - IOHandler.load = load; // shells (v8, JavaScriptCore, Spidermonkey) } + IOHandler.load = async (file) => loadFunc(file); // read: function that just reads a file into a variable - if (!globalThis.read){ + let readFunc = globalThis.read; // shells (v8, JavaScriptCore, Spidermonkey) + if (!readFunc){ if (typeof WScript !== "undefined"){ - IOHandler.read = WScript.LoadBinaryFile; // Chakra + readFunc = WScript.LoadBinaryFile; // Chakra } else if (is_node) { // NodeJS const fs = require ('fs'); - IOHandler.read = function (path) { + readFunc = function (path) { return fs.readFileSync(path); }; } else if (is_browser) { // vanila JS in browser - // TODO + readFunc = fetch; } - } else { - IOHandler.read = read; // shells (v8, JavaScriptCore, Spidermonkey) } + IOHandler.read = async (file) => await readFunc(file); }, writeContentToFile: function(content, path) { @@ -264,8 +264,6 @@ while (testArguments !== undefined && testArguments.length > 0) { // cheap way to let the testing infrastructure know we're running in a browser context (or not) setenv["IsBrowserDomSupported"] = is_browser.toString().toLowerCase(); -IOHandler.load ("mono-config.js"); - var Module = { mainScriptUrlOrBlob: "dotnet.js", @@ -316,8 +314,6 @@ var Module = { }, }; -IOHandler.load ("dotnet.js"); - const IGNORE_PARAM_COUNT = -1; var App = { @@ -417,3 +413,13 @@ var App = { } } }; + +// load the config and runtime files which will start the runtime init and subsiquently the tests +IOHandler + .load ("mono-config.js") + .then(function () { + IOHandler.load ("dotnet.js"); + }) + .catch(function(err) { + fail_exec("failed to load the mono-config.js or dotnet.js files"); + }); From 93255add056f03897cfadc22571fab31894097bb Mon Sep 17 00:00:00 2001 From: Daniel-Genkin Date: Tue, 15 Jun 2021 16:00:44 -0400 Subject: [PATCH 03/17] more cleanup and fixes --- src/mono/wasm/runtime-test.js | 101 +++++++++++++++++----------------- 1 file changed, 50 insertions(+), 51 deletions(-) diff --git a/src/mono/wasm/runtime-test.js b/src/mono/wasm/runtime-test.js index f01d119717245..93ce77c743dde 100644 --- a/src/mono/wasm/runtime-test.js +++ b/src/mono/wasm/runtime-test.js @@ -8,40 +8,40 @@ const is_browser = typeof window != "undefined"; const is_node = !is_browser && typeof process != 'undefined'; // if the engine doesn't provide a console -if (typeof (console) === "undefined") { - var console = { +if (typeof (console) === "undefined"){ + console = { log: globalThis.print, clear: function () { } }; -} -globalThis.testConsole = console; - -function proxyMethod (prefix, func, asJson) { - return function() { - let args = [...arguments]; - if (asJson) { - func (JSON.stringify({ - method: prefix, - payload: args[0], - arguments: args - })); - } else { - func([prefix + args[0], ...args.slice(1)]); - } + function proxyMethod (prefix, func, asJson) { + let method = function() { + let args = [...arguments]; + if (asJson) { + func (JSON.stringify({ + method: prefix, + payload: args[0], + arguments: args + })); + } else { + func([prefix + args[0], ...args.slice(1)]); + } + }; + + return method; }; -}; -var methods = ["debug", "trace", "warn", "info", "error"]; -for (var m of methods) { - if (typeof(console[m]) != "function") { - console[m] = proxyMethod(`console.${m}: `, console.log, false); + var methods = ["debug", "trace", "warn", "info", "error"]; + for (var m of methods) { + if (typeof(console[m]) !== "function") { + console[m] = proxyMethod(`console.${m}: `, console.log, false); + } } -} -function proxyJson (func) { - for (var m of ["log", ...methods]) - console[m] = proxyMethod(`console.${m}`,func, true); + function proxyJson (func) { + for (var m of ["log", ...methods]) + console[m] = proxyMethod(`console.${m}`,func, true); + } } if (is_browser) { @@ -50,7 +50,7 @@ if (is_browser) { let consoleWebSocket = new WebSocket(consoleUrl); consoleWebSocket.onopen = function(event) { proxyJson(function (msg) { consoleWebSocket.send (msg); }); - globalThis.testConsole.log("browser: Console websocket connected."); + console.log("browser: Console websocket connected."); }; consoleWebSocket.onerror = function(event) { console.log(`websocket error: ${event}`); @@ -67,10 +67,6 @@ if (is_browser) { } //proxyJson(console.log); - -let print = globalThis.testConsole.log; -let printErr = globalThis.testConsole.error; - if (typeof crypto === 'undefined') { // **NOTE** this is a simple insecure polyfill for testing purposes only // /dev/random doesn't work on js shells, so define our own @@ -94,20 +90,21 @@ if (typeof performance === 'undefined') { let testArguments = []; try { - if (typeof arguments === "undefined") { - if (is_node) - testArguments = process.argv.slice (2); + if (is_node) { + testArguments = process.argv.slice (2); - if (typeof scriptArgs !== "undefined") + }else if (typeof arguments === "undefined") { + if (typeof scriptArgs !== "undefined") { testArguments = scriptArgs; - else if (typeof WScript !== "undefined" && WScript.Arguments) + }else if (typeof WScript !== "undefined" && WScript.Arguments){ testArguments = WScript.Arguments; + } } else{ testArguments = arguments; } } catch (e) { - console.err(e) + console.error(e) } if (is_node) { @@ -199,18 +196,21 @@ function test_exit (exit_code) { if (is_browser) { // Notify the selenium script Module.exit_code = exit_code; - Module.print ("WASM EXIT " + exit_code); + console.log ("WASM EXIT " + exit_code); var tests_done_elem = document.createElement ("label"); tests_done_elem.id = "tests_done"; tests_done_elem.innerHTML = exit_code.toString (); document.body.appendChild (tests_done_elem); + } else if (is_node) { + Module.exit_code = exit_code; + console.log ("WASM EXIT " + exit_code); } else { Module.wasm_exit (exit_code); } } function fail_exec (reason) { - Module.print (reason); + console.error (reason); test_exit (1); } @@ -224,7 +224,7 @@ function inspect_object (o) { } // Preprocess arguments -console.info("Arguments: " + testArguments); +console.log("Arguments: " + testArguments); let profilers = []; let setenv = {}; let runtime_args = []; @@ -247,7 +247,7 @@ while (testArguments !== undefined && testArguments.length > 0) { testArguments = testArguments.slice (1); } else if (testArguments [0].startsWith ("--runtime-arg=")) { var arg = testArguments [0].substring ("--runtime-arg=".length); - runtime_testArguments.push (arg); + runtime_args = testArguments.push (arg); testArguments = testArguments.slice (1); } else if (testArguments [0] == "--disable-on-demand-gc") { enable_gc = false; @@ -264,21 +264,19 @@ while (testArguments !== undefined && testArguments.length > 0) { // cheap way to let the testing infrastructure know we're running in a browser context (or not) setenv["IsBrowserDomSupported"] = is_browser.toString().toLowerCase(); -var Module = { +export var Module = { mainScriptUrlOrBlob: "dotnet.js", - print, - printErr, - onAbort: function(x) { - print ("ABORT: " + x); + console.log ("ABORT: " + x); var err = new Error(); - print ("Stacktrace: \n"); - print (err.stack); + console.log ("Stacktrace: \n"); + console.log (err.stack); test_exit (1); }, onRuntimeInitialized: function () { + console.log("test") // Have to set env vars here to enable setting MONO_LOG_LEVEL etc. for (var variable in setenv) { MONO.mono_wasm_setenv (variable, setenv [variable]); @@ -342,10 +340,10 @@ var App = { var res = 0; try { res = exec_regression (10, testArguments[1]); - Module.print ("REGRESSION RESULT: " + res); + console.log ("REGRESSION RESULT: " + res); } catch (e) { - Module.print ("ABORT: " + e); - print (e.stack); + console.error ("ABORT: " + e); + console.error (e.stack); res = 1; } @@ -421,5 +419,6 @@ IOHandler IOHandler.load ("dotnet.js"); }) .catch(function(err) { + console.error(err) fail_exec("failed to load the mono-config.js or dotnet.js files"); }); From 7f9105f3f04bf45465400c61c031150024a5917d Mon Sep 17 00:00:00 2001 From: Daniel-Genkin Date: Wed, 16 Jun 2021 10:45:18 -0400 Subject: [PATCH 04/17] removed export --- src/mono/wasm/runtime-test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mono/wasm/runtime-test.js b/src/mono/wasm/runtime-test.js index 93ce77c743dde..afdc53dabea4d 100644 --- a/src/mono/wasm/runtime-test.js +++ b/src/mono/wasm/runtime-test.js @@ -264,7 +264,7 @@ while (testArguments !== undefined && testArguments.length > 0) { // cheap way to let the testing infrastructure know we're running in a browser context (or not) setenv["IsBrowserDomSupported"] = is_browser.toString().toLowerCase(); -export var Module = { +var Module = { mainScriptUrlOrBlob: "dotnet.js", onAbort: function(x) { From 9489f23e304a8af1c61d714c651c56b923482f33 Mon Sep 17 00:00:00 2001 From: Daniel-Genkin Date: Wed, 16 Jun 2021 11:00:27 -0400 Subject: [PATCH 05/17] more cleanup --- src/mono/wasm/runtime-test.js | 50 +++++++++++++++++------------------ 1 file changed, 24 insertions(+), 26 deletions(-) diff --git a/src/mono/wasm/runtime-test.js b/src/mono/wasm/runtime-test.js index afdc53dabea4d..ee4acd5b66280 100644 --- a/src/mono/wasm/runtime-test.js +++ b/src/mono/wasm/runtime-test.js @@ -13,37 +13,36 @@ if (typeof (console) === "undefined"){ log: globalThis.print, clear: function () { } }; - - function proxyMethod (prefix, func, asJson) { - let method = function() { - let args = [...arguments]; - if (asJson) { - func (JSON.stringify({ - method: prefix, - payload: args[0], - arguments: args - })); - } else { - func([prefix + args[0], ...args.slice(1)]); - } - }; - - return method; +} +function proxyMethod (prefix, func, asJson) { + let method = function() { + let args = [...arguments]; + if (asJson) { + func (JSON.stringify({ + method: prefix, + payload: args[0], + arguments: args + })); + } else { + func([prefix + args[0], ...args.slice(1)]); + } }; - var methods = ["debug", "trace", "warn", "info", "error"]; - for (var m of methods) { - if (typeof(console[m]) !== "function") { - console[m] = proxyMethod(`console.${m}: `, console.log, false); - } - } + return method; +}; - function proxyJson (func) { - for (var m of ["log", ...methods]) - console[m] = proxyMethod(`console.${m}`,func, true); +var methods = ["debug", "trace", "warn", "info", "error"]; +for (var m of methods) { + if (typeof(console[m]) !== "function") { + console[m] = proxyMethod(`console.${m}: `, console.log, false); } } +function proxyJson (func) { + for (var m of ["log", ...methods]) + console[m] = proxyMethod(`console.${m}`,func, true); +} + if (is_browser) { const consoleUrl = `${window.location.origin}/console`.replace('http://', 'ws://'); @@ -276,7 +275,6 @@ var Module = { }, onRuntimeInitialized: function () { - console.log("test") // Have to set env vars here to enable setting MONO_LOG_LEVEL etc. for (var variable in setenv) { MONO.mono_wasm_setenv (variable, setenv [variable]); From 57fd10cb6fa318f4b547f5d26cea781f8c3c6332 Mon Sep 17 00:00:00 2001 From: Daniel-Genkin Date: Wed, 16 Jun 2021 11:03:52 -0400 Subject: [PATCH 06/17] more cleanup --- src/mono/wasm/runtime-test.js | 37 +++++++++++++++++------------------ 1 file changed, 18 insertions(+), 19 deletions(-) diff --git a/src/mono/wasm/runtime-test.js b/src/mono/wasm/runtime-test.js index ee4acd5b66280..aacb5d07ceb01 100644 --- a/src/mono/wasm/runtime-test.js +++ b/src/mono/wasm/runtime-test.js @@ -54,19 +54,11 @@ if (is_browser) { consoleWebSocket.onerror = function(event) { console.log(`websocket error: ${event}`); }; - - // We expect to be run by tests/runtime/run.js which passes in the arguments using http parameters - var url = new URL (decodeURI (window.location)); - arguments = []; - for (var v of url.searchParams) { - if (v [0] == "arg") { - arguments.push (v [1]); - } - } } -//proxyJson(console.log); -if (typeof crypto === 'undefined') { +if (is_node) { + var crypto = require('crypto'); +} else if (typeof crypto === 'undefined') { // **NOTE** this is a simple insecure polyfill for testing purposes only // /dev/random doesn't work on js shells, so define our own // See library_fs.js:createDefaultDevices () @@ -77,8 +69,9 @@ if (typeof crypto === 'undefined') { } } } - -if (typeof performance === 'undefined') { +if (is_node) { + var { performance, PerformanceObserver } = require("perf_hooks"); +} else if (typeof performance === 'undefined') { // performance.now() is used by emscripten and doesn't work in JSC var performance = { now: function () { @@ -87,11 +80,21 @@ if (typeof performance === 'undefined') { } } +// get arguments let testArguments = []; try { if (is_node) { testArguments = process.argv.slice (2); + }else if (is_browser) { + // We expect to be run by tests/runtime/run.js which passes in the arguments using http parameters + var url = new URL (decodeURI (window.location)); + for (var param of url.searchParams) { + if (param [0] == "arg") { + testArguments.push (param [1]); + } + } + }else if (typeof arguments === "undefined") { if (typeof scriptArgs !== "undefined") { testArguments = scriptArgs; @@ -106,10 +109,7 @@ try { console.error(e) } -if (is_node) { - var { performance, PerformanceObserver } = require("perf_hooks"); -} - +// abstract all IO into a compact universally available method so that it is consistent and reliable const IOHandler = { load: null, read: null, @@ -189,8 +189,6 @@ const IOHandler = { IOHandler.init(); // end of all the nice shell glue code. -// set up a global variable to be accessed in App.init - function test_exit (exit_code) { if (is_browser) { // Notify the selenium script @@ -411,6 +409,7 @@ var App = { }; // load the config and runtime files which will start the runtime init and subsiquently the tests +// uses promise chain as loading is async but we can't use await here IOHandler .load ("mono-config.js") .then(function () { From e6e56158ddc8dc8c4879d2b52b8f9288e43e38ee Mon Sep 17 00:00:00 2001 From: Daniel-Genkin Date: Wed, 16 Jun 2021 11:08:47 -0400 Subject: [PATCH 07/17] removed unused variables --- src/mono/wasm/runtime-test.js | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/src/mono/wasm/runtime-test.js b/src/mono/wasm/runtime-test.js index aacb5d07ceb01..011f0bc3b494c 100644 --- a/src/mono/wasm/runtime-test.js +++ b/src/mono/wasm/runtime-test.js @@ -70,7 +70,7 @@ if (is_node) { } } if (is_node) { - var { performance, PerformanceObserver } = require("perf_hooks"); + var { performance } = require("perf_hooks"); } else if (typeof performance === 'undefined') { // performance.now() is used by emscripten and doesn't work in JSC var performance = { @@ -211,22 +211,12 @@ function fail_exec (reason) { test_exit (1); } -function inspect_object (o) { - var r = ""; - for(var p in o) { - var t = typeof o[p]; - r += "'" + p + "' => '" + t + "', "; - } - return r; -} - // Preprocess arguments console.log("Arguments: " + testArguments); let profilers = []; let setenv = {}; let runtime_args = []; let enable_gc = true; -let enable_zoneinfo = false; let working_dir='/'; while (testArguments !== undefined && testArguments.length > 0) { if (testArguments [0].startsWith ("--profile=")) { @@ -308,8 +298,6 @@ var Module = { }, }; -const IGNORE_PARAM_COUNT = -1; - var App = { init: function () { var wasm_set_main_args = Module.cwrap ('mono_wasm_set_main_args', 'void', ['number', 'number']); From 1d60b575dc54ef39e6f9441ae077733fa50daaa7 Mon Sep 17 00:00:00 2001 From: Daniel-Genkin Date: Wed, 16 Jun 2021 11:31:14 -0400 Subject: [PATCH 08/17] var -> let or const --- src/mono/wasm/runtime-test.js | 60 +++++++++++++++++------------------ 1 file changed, 30 insertions(+), 30 deletions(-) diff --git a/src/mono/wasm/runtime-test.js b/src/mono/wasm/runtime-test.js index 011f0bc3b494c..b47522d17388a 100644 --- a/src/mono/wasm/runtime-test.js +++ b/src/mono/wasm/runtime-test.js @@ -31,15 +31,15 @@ function proxyMethod (prefix, func, asJson) { return method; }; -var methods = ["debug", "trace", "warn", "info", "error"]; -for (var m of methods) { +const methods = ["debug", "trace", "warn", "info", "error"]; +for (let m of methods) { if (typeof(console[m]) !== "function") { console[m] = proxyMethod(`console.${m}: `, console.log, false); } } function proxyJson (func) { - for (var m of ["log", ...methods]) + for (let m of ["log", ...methods]) console[m] = proxyMethod(`console.${m}`,func, true); } @@ -88,8 +88,8 @@ try { }else if (is_browser) { // We expect to be run by tests/runtime/run.js which passes in the arguments using http parameters - var url = new URL (decodeURI (window.location)); - for (var param of url.searchParams) { + const url = new URL (decodeURI (window.location)); + for (let param of url.searchParams) { if (param [0] == "arg") { testArguments.push (param [1]); } @@ -194,7 +194,7 @@ function test_exit (exit_code) { // Notify the selenium script Module.exit_code = exit_code; console.log ("WASM EXIT " + exit_code); - var tests_done_elem = document.createElement ("label"); + const tests_done_elem = document.createElement ("label"); tests_done_elem.id = "tests_done"; tests_done_elem.innerHTML = exit_code.toString (); document.body.appendChild (tests_done_elem); @@ -220,27 +220,27 @@ let enable_gc = true; let working_dir='/'; while (testArguments !== undefined && testArguments.length > 0) { if (testArguments [0].startsWith ("--profile=")) { - var arg = testArguments [0].substring ("--profile=".length); + const arg = testArguments [0].substring ("--profile=".length); profilers.push (arg); testArguments = testArguments.slice (1); } else if (testArguments [0].startsWith ("--setenv=")) { - var arg = testArguments [0].substring ("--setenv=".length); - var parts = arg.split ('='); + const arg = testArguments [0].substring ("--setenv=".length); + const parts = arg.split ('='); if (parts.length != 2) fail_exec ("Error: malformed argument: '" + testArguments [0]); setenv [parts [0]] = parts [1]; testArguments = testArguments.slice (1); } else if (testArguments [0].startsWith ("--runtime-arg=")) { - var arg = testArguments [0].substring ("--runtime-arg=".length); + const arg = testArguments [0].substring ("--runtime-arg=".length); runtime_args = testArguments.push (arg); testArguments = testArguments.slice (1); } else if (testArguments [0] == "--disable-on-demand-gc") { enable_gc = false; testArguments = testArguments.slice (1); } else if (testArguments [0].startsWith ("--working-dir=")) { - var arg = testArguments [0].substring ("--working-dir=".length); + const arg = testArguments [0].substring ("--working-dir=".length); working_dir = arg; testArguments = testArguments.slice (1); } else { @@ -251,12 +251,13 @@ while (testArguments !== undefined && testArguments.length > 0) { // cheap way to let the testing infrastructure know we're running in a browser context (or not) setenv["IsBrowserDomSupported"] = is_browser.toString().toLowerCase(); +// must be var as dotnet.js uses it var Module = { mainScriptUrlOrBlob: "dotnet.js", onAbort: function(x) { console.log ("ABORT: " + x); - var err = new Error(); + const err = new Error(); console.log ("Stacktrace: \n"); console.log (err.stack); test_exit (1); @@ -264,7 +265,7 @@ var Module = { onRuntimeInitialized: function () { // Have to set env vars here to enable setting MONO_LOG_LEVEL etc. - for (var variable in setenv) { + for (let variable in setenv) { MONO.mono_wasm_setenv (variable, setenv [variable]); } @@ -287,8 +288,8 @@ var Module = { // for testing purposes add BCL assets to VFS until we special case File.Open // to identify when an assembly from the BCL is being open and resolve it correctly. /* - var content = new Uint8Array (read (asset, 'binary')); - var path = asset.substr(config.deploy_prefix.length); + const content = new Uint8Array (read (asset, 'binary')); + const path = asset.substr(config.deploy_prefix.length); IOHandler.writeContentToFile(content, path); */ return IOHandler.fetch (asset, { credentials: 'same-origin' }); @@ -298,18 +299,17 @@ var Module = { }, }; -var App = { +const App = { init: function () { - var wasm_set_main_args = Module.cwrap ('mono_wasm_set_main_args', 'void', ['number', 'number']); - var wasm_strdup = Module.cwrap ('mono_wasm_strdup', 'number', ['string']); + const wasm_set_main_args = Module.cwrap ('mono_wasm_set_main_args', 'void', ['number', 'number']); + const wasm_strdup = Module.cwrap ('mono_wasm_strdup', 'number', ['string']); Module.wasm_exit = Module.cwrap ('mono_wasm_exit', 'void', ['number']); console.info("Initializing....."); - for (var i = 0; i < profilers.length; ++i) { - var init = Module.cwrap ('mono_wasm_load_profiler_' + profilers [i], 'void', ['string']) - + for (let i = 0; i < profilers.length; ++i) { + const init = Module.cwrap ('mono_wasm_load_profiler_' + profilers [i], 'void', ['string']) init (""); } @@ -319,9 +319,9 @@ var App = { } if (testArguments[0] == "--regression") { - var exec_regression = Module.cwrap ('mono_wasm_exec_regression', 'number', ['number', 'string']) + const exec_regression = Module.cwrap ('mono_wasm_exec_regression', 'number', ['number', 'string']) - var res = 0; + let res = 0; try { res = exec_regression (10, testArguments[1]); console.log ("REGRESSION RESULT: " + res); @@ -348,22 +348,22 @@ var App = { } main_assembly_name = testArguments[1]; - var app_args = testArguments.slice (2); + const app_args = testArguments.slice (2); - var main_argc = testArguments.length - 2 + 1; - var main_argv = Module._malloc (main_argc * 4); + const main_argc = testArguments.length - 2 + 1; + const main_argv = Module._malloc (main_argc * 4); aindex = 0; Module.setValue (main_argv + (aindex * 4), wasm_strdup (testArguments [1]), "i32") aindex += 1; - for (var i = 2; i < testArguments.length; ++i) { + for (let i = 2; i < testArguments.length; ++i) { Module.setValue (main_argv + (aindex * 4), wasm_strdup (testArguments [i]), "i32"); aindex += 1; } wasm_set_main_args (main_argc, main_argv); // Automatic signature isn't working correctly - let result = Module.mono_call_assembly_entry_point (main_assembly_name, [app_args], "m"); - let onError = function (error) + const result = Module.mono_call_assembly_entry_point (main_assembly_name, [app_args], "m"); + const onError = function (error) { console.error (error); if (error.stack) @@ -386,7 +386,7 @@ var App = { if ((arguments.length > 2) && (typeof (signature) !== "string")) throw new Error("Invalid number of arguments for call_test_method"); - var fqn = "[System.Private.Runtime.InteropServices.JavaScript.Tests]System.Runtime.InteropServices.JavaScript.Tests.HelperMarshal:" + method_name; + const fqn = "[System.Private.Runtime.InteropServices.JavaScript.Tests]System.Runtime.InteropServices.JavaScript.Tests.HelperMarshal:" + method_name; try { return BINDING.call_static_method(fqn, args || [], signature); } catch (exc) { From 3253d861a74bfb02cac55bf9b37608eca3d81d9d Mon Sep 17 00:00:00 2001 From: Daniel-Genkin Date: Wed, 16 Jun 2021 14:44:39 -0400 Subject: [PATCH 09/17] slight readability fix --- src/mono/wasm/runtime-test.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/mono/wasm/runtime-test.js b/src/mono/wasm/runtime-test.js index b47522d17388a..2c3857a233a7e 100644 --- a/src/mono/wasm/runtime-test.js +++ b/src/mono/wasm/runtime-test.js @@ -15,7 +15,7 @@ if (typeof (console) === "undefined"){ }; } function proxyMethod (prefix, func, asJson) { - let method = function() { + return function() { let args = [...arguments]; if (asJson) { func (JSON.stringify({ @@ -27,8 +27,6 @@ function proxyMethod (prefix, func, asJson) { func([prefix + args[0], ...args.slice(1)]); } }; - - return method; }; const methods = ["debug", "trace", "warn", "info", "error"]; From eef11f481f45cf9d19f546948d7ee4bfe7b7918d Mon Sep 17 00:00:00 2001 From: Daniel-Genkin Date: Thu, 17 Jun 2021 09:56:57 -0400 Subject: [PATCH 10/17] Addressed PR comments --- src/mono/wasm/runtime-test.js | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/mono/wasm/runtime-test.js b/src/mono/wasm/runtime-test.js index 2c3857a233a7e..bcfc99084013f 100644 --- a/src/mono/wasm/runtime-test.js +++ b/src/mono/wasm/runtime-test.js @@ -50,7 +50,7 @@ if (is_browser) { console.log("browser: Console websocket connected."); }; consoleWebSocket.onerror = function(event) { - console.log(`websocket error: ${event}`); + console.error(`websocket error: ${event}`); }; } @@ -104,7 +104,7 @@ try { testArguments = arguments; } } catch (e) { - console.error(e) + console.error(e); } // abstract all IO into a compact universally available method so that it is consistent and reliable @@ -257,7 +257,7 @@ var Module = { console.log ("ABORT: " + x); const err = new Error(); console.log ("Stacktrace: \n"); - console.log (err.stack); + console.err (err.stack); test_exit (1); }, @@ -307,7 +307,7 @@ const App = { console.info("Initializing....."); for (let i = 0; i < profilers.length; ++i) { - const init = Module.cwrap ('mono_wasm_load_profiler_' + profilers [i], 'void', ['string']) + const init = Module.cwrap ('mono_wasm_load_profiler_' + profilers [i], 'void', ['string']); init (""); } @@ -317,7 +317,7 @@ const App = { } if (testArguments[0] == "--regression") { - const exec_regression = Module.cwrap ('mono_wasm_exec_regression', 'number', ['number', 'string']) + const exec_regression = Module.cwrap ('mono_wasm_exec_regression', 'number', ['number', 'string']); let res = 0; try { @@ -351,7 +351,7 @@ const App = { const main_argc = testArguments.length - 2 + 1; const main_argv = Module._malloc (main_argc * 4); aindex = 0; - Module.setValue (main_argv + (aindex * 4), wasm_strdup (testArguments [1]), "i32") + Module.setValue (main_argv + (aindex * 4), wasm_strdup (testArguments [1]), "i32"); aindex += 1; for (let i = 2; i < testArguments.length; ++i) { Module.setValue (main_argv + (aindex * 4), wasm_strdup (testArguments [i]), "i32"); @@ -402,6 +402,6 @@ IOHandler IOHandler.load ("dotnet.js"); }) .catch(function(err) { - console.error(err) + console.error(err); fail_exec("failed to load the mono-config.js or dotnet.js files"); }); From ac87c4252f81b56ea60738e6e0f6e4a158a4f111 Mon Sep 17 00:00:00 2001 From: Daniel-Genkin Date: Thu, 17 Jun 2021 09:58:31 -0400 Subject: [PATCH 11/17] Fixed typo --- src/mono/wasm/runtime-test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mono/wasm/runtime-test.js b/src/mono/wasm/runtime-test.js index bcfc99084013f..2eb1203d6141c 100644 --- a/src/mono/wasm/runtime-test.js +++ b/src/mono/wasm/runtime-test.js @@ -257,7 +257,7 @@ var Module = { console.log ("ABORT: " + x); const err = new Error(); console.log ("Stacktrace: \n"); - console.err (err.stack); + console.error (err.stack); test_exit (1); }, From 7fd1a1a8fec73a6767ad22add4a48fb659d02fde Mon Sep 17 00:00:00 2001 From: Daniel-Genkin Date: Fri, 18 Jun 2021 11:57:20 -0400 Subject: [PATCH 12/17] prep io for nodejs + comments --- src/mono/wasm/runtime-test.js | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/src/mono/wasm/runtime-test.js b/src/mono/wasm/runtime-test.js index 2eb1203d6141c..e19ed861b373b 100644 --- a/src/mono/wasm/runtime-test.js +++ b/src/mono/wasm/runtime-test.js @@ -109,8 +109,8 @@ try { // abstract all IO into a compact universally available method so that it is consistent and reliable const IOHandler = { - load: null, - read: null, + load: null, // load js file into project and evaluate it + read: null, // return the contents of a file as a string init: function() { // load: function that loads and executes a script @@ -143,7 +143,7 @@ const IOHandler = { } else if (is_node) { // NodeJS const fs = require ('fs'); readFunc = function (path) { - return fs.readFileSync(path); + return fs.readFileSync(path).toString(); }; } else if (is_browser) { // vanila JS in browser readFunc = fetch; @@ -152,20 +152,27 @@ const IOHandler = { IOHandler.read = async (file) => await readFunc(file); }, - writeContentToFile: function(content, path) { + writeContentToFile: function(content, path) { // writes a string to a file const stream = FS.open(path, 'w+'); FS.write(stream, content, 0, content.length, 0); FS.close(stream); }, - fetch: function(asset, params) { - if (is_node || is_browser) { + fetch: function(asset, params) { // returns an async fetch request in the form of {ok: boolean, url: string, arrayBuffer: Promise} + if (is_browser) { return fetch (asset, params); - } else { + + } else { // shells and node return new Promise ((resolve, reject) => { let bytes = null, error = null; try { - bytes = read (asset, 'binary'); + if (is_node){ + const fs = require ('fs'); + const buffer = fs.readFileSync(asset); + bytes = buffer.buffer; + } else { + bytes = read (asset, 'binary'); + } } catch (exc) { error = exc; } From 9624ecee75466059e2886024667d4f62a252429f Mon Sep 17 00:00:00 2001 From: Daniel-Genkin Date: Mon, 21 Jun 2021 10:33:03 -0400 Subject: [PATCH 13/17] Fixed merge conflicts --- src/mono/wasm/runtime-test.js | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/src/mono/wasm/runtime-test.js b/src/mono/wasm/runtime-test.js index e19ed861b373b..53ebce95421a0 100644 --- a/src/mono/wasm/runtime-test.js +++ b/src/mono/wasm/runtime-test.js @@ -259,6 +259,11 @@ setenv["IsBrowserDomSupported"] = is_browser.toString().toLowerCase(); // must be var as dotnet.js uses it var Module = { mainScriptUrlOrBlob: "dotnet.js", + config: null, + + preInit: async function() { + Module.config = await MONO.mono_wasm_load_config("./mono-config.json"); + }, onAbort: function(x) { console.log ("ABORT: " + x); @@ -278,7 +283,7 @@ var Module = { Module.ccall ('mono_wasm_enable_on_demand_gc', 'void', ['number'], [0]); } - config.loaded_cb = function () { + Module.config.loaded_cb = function () { let wds = FS.stat (working_dir); if (wds === undefined || !FS.isDir (wds.mode)) { fail_exec (`Could not find working directory ${working_dir}`); @@ -288,19 +293,19 @@ var Module = { FS.chdir (working_dir); App.init (); }; - config.fetch_file_cb = function (asset) { + Module.config.fetch_file_cb = function (asset) { // console.log("fetch_file_cb('" + asset + "')"); // for testing purposes add BCL assets to VFS until we special case File.Open // to identify when an assembly from the BCL is being open and resolve it correctly. /* - const content = new Uint8Array (read (asset, 'binary')); - const path = asset.substr(config.deploy_prefix.length); - IOHandler.writeContentToFile(content, path); + var content = new Uint8Array (read (asset, 'binary')); + var path = asset.substr(Module.config.deploy_prefix.length); + writeContentToFile(content, path); */ return IOHandler.fetch (asset, { credentials: 'same-origin' }); }; - MONO.mono_load_runtime_and_bcl_args (config); + MONO.mono_load_runtime_and_bcl_args (Module.config); }, }; From 19a5f6927feb8409aa3da4af3fdecd8bb542b609 Mon Sep 17 00:00:00 2001 From: Daniel-Genkin Date: Mon, 21 Jun 2021 19:01:13 -0400 Subject: [PATCH 14/17] Fixed failing tests --- src/mono/wasm/runtime-test.js | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/src/mono/wasm/runtime-test.js b/src/mono/wasm/runtime-test.js index 262c0270defb5..44c86c7885ed2 100644 --- a/src/mono/wasm/runtime-test.js +++ b/src/mono/wasm/runtime-test.js @@ -261,9 +261,9 @@ var Module = { mainScriptUrlOrBlob: "dotnet.js", config: null, - preInit: async function() { - Module.config = await MONO.mono_wasm_load_config("./mono-config.json"); - }, + preInit: async function() { + Module.config = await MONO.mono_wasm_load_config("./mono-config.json"); + }, onAbort: function(x) { console.log ("ABORT: " + x); @@ -409,10 +409,7 @@ const App = { // load the config and runtime files which will start the runtime init and subsiquently the tests // uses promise chain as loading is async but we can't use await here IOHandler - .load ("mono-config.js") - .then(function () { - IOHandler.load ("dotnet.js"); - }) + .load ("dotnet.js") .catch(function(err) { console.error(err); fail_exec("failed to load the mono-config.js or dotnet.js files"); From 11be10d9b16d8d723662444ddb4433b229cbb097 Mon Sep 17 00:00:00 2001 From: Daniel-Genkin Date: Tue, 22 Jun 2021 11:41:22 -0400 Subject: [PATCH 15/17] Addressed PR comments about formatting issues --- src/mono/wasm/runtime-test.js | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/src/mono/wasm/runtime-test.js b/src/mono/wasm/runtime-test.js index 44c86c7885ed2..bc1ac54c19fb9 100644 --- a/src/mono/wasm/runtime-test.js +++ b/src/mono/wasm/runtime-test.js @@ -8,7 +8,7 @@ const is_browser = typeof window != "undefined"; const is_node = !is_browser && typeof process != 'undefined'; // if the engine doesn't provide a console -if (typeof (console) === "undefined"){ +if (typeof (console) === "undefined") { console = { log: globalThis.print, clear: function () { } @@ -84,7 +84,7 @@ try { if (is_node) { testArguments = process.argv.slice (2); - }else if (is_browser) { + } else if (is_browser) { // We expect to be run by tests/runtime/run.js which passes in the arguments using http parameters const url = new URL (decodeURI (window.location)); for (let param of url.searchParams) { @@ -93,14 +93,14 @@ try { } } - }else if (typeof arguments === "undefined") { + } else if (typeof arguments === "undefined") { if (typeof scriptArgs !== "undefined") { testArguments = scriptArgs; - }else if (typeof WScript !== "undefined" && WScript.Arguments){ + } else if (typeof WScript !== "undefined" && WScript.Arguments) { testArguments = WScript.Arguments; } - } else{ + } else { testArguments = arguments; } } catch (e) { @@ -115,8 +115,8 @@ const IOHandler = { init: function() { // load: function that loads and executes a script let loadFunc = globalThis.load; // shells (v8, JavaScriptCore, Spidermonkey) - if (!loadFunc){ - if (typeof WScript !== "undefined"){ // Chakra + if (!loadFunc) { + if (typeof WScript !== "undefined") { // Chakra loadFunc = WScript.LoadScriptFile; } else if (is_node) { // NodeJS @@ -136,8 +136,8 @@ const IOHandler = { // read: function that just reads a file into a variable let readFunc = globalThis.read; // shells (v8, JavaScriptCore, Spidermonkey) - if (!readFunc){ - if (typeof WScript !== "undefined"){ + if (!readFunc) { + if (typeof WScript !== "undefined") { readFunc = WScript.LoadBinaryFile; // Chakra } else if (is_node) { // NodeJS @@ -166,7 +166,7 @@ const IOHandler = { return new Promise ((resolve, reject) => { let bytes = null, error = null; try { - if (is_node){ + if (is_node) { const fs = require ('fs'); const buffer = fs.readFileSync(asset); bytes = buffer.buffer; @@ -176,7 +176,9 @@ const IOHandler = { } catch (exc) { error = exc; } - const response = { ok: (bytes && !error), url: asset, + const response = { + ok: (bytes && !error), + url: asset, arrayBuffer: function () { return new Promise ((resolve2, reject2) => { if (error) @@ -187,7 +189,7 @@ const IOHandler = { )} } resolve (response); - }) + }); } } }; From d0388ed243634b436e0aacd230ae0c5afa3294d0 Mon Sep 17 00:00:00 2001 From: Daniel-Genkin Date: Wed, 23 Jun 2021 14:03:38 -0400 Subject: [PATCH 16/17] added type defintions --- src/mono/wasm/runtime-test.js | 57 ++++++++++++++++++++++++++++++----- 1 file changed, 49 insertions(+), 8 deletions(-) diff --git a/src/mono/wasm/runtime-test.js b/src/mono/wasm/runtime-test.js index bc1ac54c19fb9..7b768d70ce997 100644 --- a/src/mono/wasm/runtime-test.js +++ b/src/mono/wasm/runtime-test.js @@ -109,9 +109,22 @@ try { // abstract all IO into a compact universally available method so that it is consistent and reliable const IOHandler = { - load: null, // load js file into project and evaluate it - read: null, // return the contents of a file as a string - + /** Load js file into project and evaluate it + * @type {(file: string) => Promise} + * @param {string} file path to the file to load + */ + load: null, + + /** Read and return the contents of a file as a string + * @type {(file: string) => Promise} + * @param {string} file the path to the file to read + * @return {string} the contents of the file + */ + read: null, + + /** Sets up the load and read functions for later + * @type {() => void} + */ init: function() { // load: function that loads and executes a script let loadFunc = globalThis.load; // shells (v8, JavaScriptCore, Spidermonkey) @@ -152,15 +165,26 @@ const IOHandler = { IOHandler.read = async (file) => await readFunc(file); }, + /** Write the content to a file at a certain path + * @type {(content: string, path: string) => void} + * @param {string} content the contents to write to the file + * @param {string} path the path to which to write the contents + */ writeContentToFile: function(content, path) { // writes a string to a file const stream = FS.open(path, 'w+'); FS.write(stream, content, 0, content.length, 0); FS.close(stream); }, - fetch: function(asset, params) { // returns an async fetch request in the form of {ok: boolean, url: string, arrayBuffer: Promise} + /** Returns an async fetch request + * @type {(path: string, params: object) => Promise<{ok: boolean, url: string, arrayBuffer: Promise}>} + * @param {string} path the path to the file to fetch + * @param {object} params additional parameters to fetch with. Only used on browser + * @returns {Promise<{ok: boolean, url: string, arrayBuffer: Promise}>} The result of the request + */ + fetch: function(path, params) { if (is_browser) { - return fetch (asset, params); + return fetch (path, params); } else { // shells and node return new Promise ((resolve, reject) => { @@ -168,17 +192,17 @@ const IOHandler = { try { if (is_node) { const fs = require ('fs'); - const buffer = fs.readFileSync(asset); + const buffer = fs.readFileSync(path); bytes = buffer.buffer; } else { - bytes = read (asset, 'binary'); + bytes = read (path, 'binary'); } } catch (exc) { error = exc; } const response = { ok: (bytes && !error), - url: asset, + url: path, arrayBuffer: function () { return new Promise ((resolve2, reject2) => { if (error) @@ -263,10 +287,17 @@ var Module = { mainScriptUrlOrBlob: "dotnet.js", config: null, + /** Called before the runtime is loaded and before it is run + * @type {() => Promise} + */ preInit: async function() { Module.config = await MONO.mono_wasm_load_config("./mono-config.json"); }, + /** Called after an exception occurs during execution + * @type {(x: string|number=) => void} + * @param {string|number} x error message + */ onAbort: function(x) { console.log ("ABORT: " + x); const err = new Error(); @@ -275,6 +306,9 @@ var Module = { test_exit (1); }, + /** Called after the runtime is loaded but before it is run mostly prepares runtime and config for the tests + * @type {() => void} + */ onRuntimeInitialized: function () { // Have to set env vars here to enable setting MONO_LOG_LEVEL etc. for (let variable in setenv) { @@ -312,6 +346,9 @@ var Module = { }; const App = { + /** Runs the tests (runtime is now loaded and running) + * @type {() => void} + */ init: function () { const wasm_set_main_args = Module.cwrap ('mono_wasm_set_main_args', 'void', ['number', 'number']); const wasm_strdup = Module.cwrap ('mono_wasm_strdup', 'number', ['string']); @@ -393,6 +430,10 @@ const App = { fail_exec ("Unhandled argument: " + testArguments [0]); } }, + + /** Runs a particular test + * @type {(method_name: string, args: any[], signature: any?) => return number} + */ call_test_method: function (method_name, args, signature) { // note: arguments here is the array of arguments passsed to this function if ((arguments.length > 2) && (typeof (signature) !== "string")) From 78d11b32d9591c210c1ec5fa527b55b688e2011b Mon Sep 17 00:00:00 2001 From: Daniel-Genkin Date: Fri, 25 Jun 2021 11:32:45 -0400 Subject: [PATCH 17/17] adjusted optional types --- src/mono/wasm/runtime-test.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/mono/wasm/runtime-test.js b/src/mono/wasm/runtime-test.js index f5b143cb015ca..dfb2958ab984c 100644 --- a/src/mono/wasm/runtime-test.js +++ b/src/mono/wasm/runtime-test.js @@ -110,13 +110,13 @@ try { // abstract all IO into a compact universally available method so that it is consistent and reliable const IOHandler = { /** Load js file into project and evaluate it - * @type {(file: string) => Promise} + * @type {(file: string) => Promise | null} * @param {string} file path to the file to load */ load: null, /** Read and return the contents of a file as a string - * @type {(file: string) => Promise} + * @type {(file: string) => Promise | null} * @param {string} file the path to the file to read * @return {string} the contents of the file */ @@ -432,7 +432,7 @@ const App = { }, /** Runs a particular test - * @type {(method_name: string, args: any[], signature: any?) => return number} + * @type {(method_name: string, args: any[]=, signature: any=) => return number} */ call_test_method: function (method_name, args, signature) { // note: arguments here is the array of arguments passsed to this function