1 // -*- mode: js; js-indent-level: 4; -*-
3 // Run runtime tests under a JS shell or a browser
6 //glue code to deal with the differences between chrome, ch, d8, jsc and sm.
7 var is_browser = typeof window != "undefined";
10 // We expect to be run by tests/runtime/run.js which passes in the arguments using http parameters
11 var url = new URL (decodeURI (window.location));
13 for (var v of url.searchParams) {
15 console.log ("URL ARG: " + v [0] + "=" + v [1]);
16 arguments.push (v [1]);
21 if (is_browser || typeof print === "undefined")
24 // JavaScript core does not have a console defined
25 if (typeof console === "undefined") {
26 var Console = function () {
27 this.log = function(msg){ print(msg) };
29 console = new Console();
32 if (typeof console !== "undefined") {
33 var has_console_warn = false;
35 if (typeof console.warn !== "undefined")
36 has_console_warn = true;
39 if (!has_console_warn)
40 console.warn = console.log;
43 if (typeof crypto == 'undefined') {
44 // /dev/random doesn't work on js shells, so define our own
45 // See library_fs.js:createDefaultDevices ()
47 getRandomValues: function (buffer) {
48 buffer[0] = (Math.random()*256)|0;
54 if (typeof arguments == "undefined")
55 arguments = WScript.Arguments;
56 load = WScript.LoadScriptFile;
57 read = WScript.LoadBinaryFile;
62 if (typeof arguments == "undefined") {
63 if (typeof scriptArgs !== "undefined")
64 arguments = scriptArgs;
68 //end of all the nice shell glue code.
70 // set up a global variable to be accessed in App.init
71 var testArguments = arguments;
73 function test_exit (exit_code) {
75 // Notify the puppeteer script
76 Module.exit_code = exit_code;
77 print ("WASM EXIT " + exit_code);
79 Module.wasm_exit (exit_code);
83 function fail_exec (reason) {
88 function inspect_object (o) {
92 r += "'" + p + "' => '" + t + "', ";
97 // Preprocess arguments
98 var args = testArguments;
99 print("Arguments: " + testArguments);
105 if (args [0].startsWith ("--profile=")) {
106 var arg = args [0].substring ("--profile=".length);
108 profilers.push (arg);
110 args = args.slice (1);
111 } else if (args [0].startsWith ("--setenv=")) {
112 var arg = args [0].substring ("--setenv=".length);
113 var parts = arg.split ('=');
114 if (parts.length != 2)
115 fail_exec ("Error: malformed argument: '" + args [0]);
116 setenv [parts [0]] = parts [1];
117 args = args.slice (1);
118 } else if (args [0].startsWith ("--runtime-arg=")) {
119 var arg = args [0].substring ("--runtime-arg=".length);
120 runtime_args.push (arg);
121 args = args.slice (1);
122 } else if (args [0] == "--enable-gc") {
124 args = args.slice (1);
129 testArguments = args;
131 if (typeof window == "undefined")
132 load ("mono-config.js");
135 mainScriptUrlOrBlob: "mono.js",
137 print: function(x) { print ("WASM: " + x) },
138 printErr: function(x) { print ("WASM-ERR: " + x) },
140 onAbort: function(x) {
141 print ("ABORT: " + x);
142 var err = new Error();
143 print ("Stacktrace: \n");
148 onRuntimeInitialized: function () {
149 // Have to set env vars here to enable setting MONO_LOG_LEVEL etc.
150 var wasm_setenv = Module.cwrap ('mono_wasm_setenv', 'void', ['string', 'string']);
151 for (var variable in setenv) {
152 MONO.mono_wasm_setenv (variable, setenv [variable]);
156 var f = Module.cwrap ('mono_wasm_enable_on_demand_gc', 'void', []);
160 MONO.mono_load_runtime_and_bcl (
162 config.deploy_prefix,
163 config.enable_debugging,
170 if (typeof window != 'undefined') {
171 return fetch (asset, { credentials: 'same-origin' });
173 // The default mono_load_runtime_and_bcl defaults to using
174 // fetch to load the assets. It also provides a way to set a
175 // fetch promise callback.
176 // Here we wrap the file read in a promise and fake a fetch response
178 return new Promise((resolve, reject) => {
179 var response = { ok: true, url: asset,
180 arrayBuffer: function() {
181 return new Promise((resolve2, reject2) => {
182 resolve2(new Uint8Array (read (asset, 'binary')));
194 if (typeof window == "undefined")
197 const IGNORE_PARAM_COUNT = -1;
202 var assembly_load = Module.cwrap ('mono_wasm_assembly_load', 'number', ['string'])
203 var find_class = Module.cwrap ('mono_wasm_assembly_find_class', 'number', ['number', 'string', 'string'])
204 var find_method = Module.cwrap ('mono_wasm_assembly_find_method', 'number', ['number', 'string', 'number'])
205 var runtime_invoke = Module.cwrap ('mono_wasm_invoke_method', 'number', ['number', 'number', 'number', 'number']);
206 var string_from_js = Module.cwrap ('mono_wasm_string_from_js', 'number', ['string']);
207 var assembly_get_entry_point = Module.cwrap ('mono_wasm_assembly_get_entry_point', 'number', ['number']);
208 var string_get_utf8 = Module.cwrap ('mono_wasm_string_get_utf8', 'string', ['number']);
209 var string_array_new = Module.cwrap ('mono_wasm_string_array_new', 'number', ['number']);
210 var obj_array_set = Module.cwrap ('mono_wasm_obj_array_set', 'void', ['number', 'number', 'number']);
211 var exit = Module.cwrap ('mono_wasm_exit', 'void', ['number']);
212 var wasm_setenv = Module.cwrap ('mono_wasm_setenv', 'void', ['string', 'string']);
213 var wasm_set_main_args = Module.cwrap ('mono_wasm_set_main_args', 'void', ['number', 'number']);
214 var wasm_strdup = Module.cwrap ('mono_wasm_strdup', 'number', ['string'])
216 Module.wasm_exit = Module.cwrap ('mono_wasm_exit', 'void', ['number']);
218 Module.print("Initializing.....");
220 for (var i = 0; i < profilers.length; ++i) {
221 var init = Module.cwrap ('mono_wasm_load_profiler_' + profilers [i], 'void', ['string'])
226 if (args[0] == "--regression") {
227 var exec_regresion = Module.cwrap ('mono_wasm_exec_regression', 'number', ['number', 'string'])
231 res = exec_regresion (10, args[1]);
232 Module.print ("REGRESSION RESULT: " + res);
234 Module.print ("ABORT: " + e);
240 fail_exec ("REGRESSION TEST FAILED");
245 if (runtime_args.length > 0)
246 MONO.mono_wasm_set_runtime_options (runtime_args);
248 if (args[0] == "--run") {
250 if (args.length == 1)
251 fail_exec ("Error: Missing main executable argument.");
252 main_assembly = assembly_load (args[1]);
253 if (main_assembly == 0)
254 fail_exec ("Error: Unable to load main executable '" + args[1] + "'");
255 main_method = assembly_get_entry_point (main_assembly);
256 if (main_method == 0)
257 fail_exec ("Error: Main (string[]) method not found.");
259 var app_args = string_array_new (args.length - 2);
260 for (var i = 2; i < args.length; ++i) {
261 obj_array_set (app_args, i - 2, string_from_js (args [i]));
264 var main_argc = args.length - 2 + 1;
265 var main_argv = Module._malloc (main_argc * 4);
267 Module.setValue (main_argv + (aindex * 4), wasm_strdup (args [1]), "i32")
269 for (var i = 2; i < args.length; ++i) {
270 Module.setValue (main_argv + (aindex * 4), wasm_strdup (args [i]), "i32");
273 wasm_set_main_args (main_argc, main_argv);
276 var invoke_args = Module._malloc (4);
277 Module.setValue (invoke_args, app_args, "i32");
278 var eh_throw = Module._malloc (4);
279 Module.setValue (eh_throw, 0, "i32");
280 var res = runtime_invoke (main_method, 0, invoke_args, eh_throw);
281 var eh_res = Module.getValue (eh_throw, "i32");
283 print ("Exception:" + string_get_utf8 (res));
287 print ("JS exception: " + ex);
297 Module.print("Initializing Binding Test Suite support.....");
299 //binding test suite support code
300 binding_test_module = assembly_load ("binding_tests");
301 if (!binding_test_module)
303 Module.printErr("Binding tests module 'binding_tests' not found. Exiting Tests.")
304 throw new Error("Binding tests module 'binding_tests' not found. Exiting Tests.");
307 binding_test_class = find_class (binding_test_module, "", "TestClass");
308 if (!binding_test_class)
310 Module.printErr("Binding tests class 'TestClass' not found. Exiting Tests.")
311 throw new Error("Binding tests class 'TestClass' not found. Exiting Tests.");
314 Module.print("Binding support complete.");
317 Module.print("Checking for [main]Driver:Send ....");
319 var send_message = undefined;
323 send_message = BINDING.bind_static_method("[main]Driver:Send");
327 Module.printErr("[main]Driver:Send not found: " + e);
332 Module.print("Driver binding complete.");
335 var main_argv = Module._malloc (main_argc * 4);
336 Module.setValue (main_argv, wasm_strdup ("mono-wasm"), "i32")
337 wasm_set_main_args (main_argc, main_argv);
339 var bad_send_msg_detected = false;
340 for (var i = 0; i < testArguments.length; ++i) {
341 if (testArguments [i] == "--exclude") {
342 send_message ("--exclude", testArguments [i + 1]);
349 res = send_message("start-test", testArguments [i])
351 Module.printErr ("BAD SEND MSG: " + e);
352 bad_send_msg_detected = true;
354 print ("-----STARTED " + testArguments [i] + "---- " + res);
356 if (res == "SUCCESS") {
357 while (send_message ("pump-test", testArguments [i]) != "DONE")
359 Module.pump_message ();
366 var status = send_message ("test-result", "");
367 print ("Test status " + status)
368 if (status != "PASS")
369 fail_exec ("BAD TEST STATUS");
371 if (bad_send_msg_detected)
372 fail_exec ("BAD MSG SEND DETECTED");
377 //binding test suite support code
378 var binding_test_module = undefined;
379 var binding_test_class = undefined;
381 // This function is called from the binding test suite
382 function call_test_method(method_name, signature, args)
384 var target_method = find_method (binding_test_class, method_name, IGNORE_PARAM_COUNT)
386 throw "Could not find " + method_name;
388 return Module.mono_method_invoke (target_method, null, signature, args);