diff --git a/src/libraries/System.Private.Runtime.InteropServices.JavaScript/tests/System/Runtime/InteropServices/JavaScript/DelegateTests.cs b/src/libraries/System.Private.Runtime.InteropServices.JavaScript/tests/System/Runtime/InteropServices/JavaScript/DelegateTests.cs index f5ef8d13a8d81..ccb9a1ade66d5 100644 --- a/src/libraries/System.Private.Runtime.InteropServices.JavaScript/tests/System/Runtime/InteropServices/JavaScript/DelegateTests.cs +++ b/src/libraries/System.Private.Runtime.InteropServices.JavaScript/tests/System/Runtime/InteropServices/JavaScript/DelegateTests.cs @@ -36,7 +36,7 @@ public static void InvokeFunctionInLoopUsingConstanceValues() Runtime.InvokeJS(@" var funcDelegate = App.call_test_method (""CreateFunctionDelegate"", [ ]); var res = funcDelegate (10, 20); - for (x = 0; x < 1000; x++) + for (let x = 0; x < 1000; x++) { res = funcDelegate (10, 20); } @@ -55,7 +55,7 @@ public static void InvokeFunctionInLoopUsingIncrementedValues() Runtime.InvokeJS(@" var funcDelegate = App.call_test_method (""CreateFunctionDelegate"", [ ]); var res = funcDelegate (10, 20); - for (x = 0; x < 1000; x++) + for (let x = 0; x < 1000; x++) { res = funcDelegate (x, x); } diff --git a/src/mono/sample/mbr/browser/runtime.js b/src/mono/sample/mbr/browser/runtime.js index 74781179a31f8..41989feb6a547 100644 --- a/src/mono/sample/mbr/browser/runtime.js +++ b/src/mono/sample/mbr/browser/runtime.js @@ -1,6 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +"use strict"; var Module = { config: null, diff --git a/src/mono/sample/wasm/browser-bench/runtime.js b/src/mono/sample/wasm/browser-bench/runtime.js index f9bdf8b3af7ab..87fb6436dbc1d 100644 --- a/src/mono/sample/wasm/browser-bench/runtime.js +++ b/src/mono/sample/wasm/browser-bench/runtime.js @@ -1,5 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. + +"use strict"; var Module = { config: null, diff --git a/src/mono/sample/wasm/browser-profile/runtime.js b/src/mono/sample/wasm/browser-profile/runtime.js index f0636985d0358..cd0dd0cb9ed32 100644 --- a/src/mono/sample/wasm/browser-profile/runtime.js +++ b/src/mono/sample/wasm/browser-profile/runtime.js @@ -1,5 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. + +"use strict"; var Module = { is_testing: false, config: null, diff --git a/src/mono/sample/wasm/browser/runtime.js b/src/mono/sample/wasm/browser/runtime.js index 816136acf36b6..904ca19958f76 100644 --- a/src/mono/sample/wasm/browser/runtime.js +++ b/src/mono/sample/wasm/browser/runtime.js @@ -1,6 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +"use strict"; var Module = { config: null, diff --git a/src/mono/wasm/debugger/tests/debugger-test/other.js b/src/mono/wasm/debugger/tests/debugger-test/other.js index c32eaa064b033..72cb80bf2fe6e 100644 --- a/src/mono/wasm/debugger/tests/debugger-test/other.js +++ b/src/mono/wasm/debugger/tests/debugger-test/other.js @@ -1,6 +1,8 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +"use strict"; + function big_array_js_test (len) { var big = new Array(len); for (let i=0; i < len; i ++) { diff --git a/src/mono/wasm/debugger/tests/debugger-test/runtime-debugger.js b/src/mono/wasm/debugger/tests/debugger-test/runtime-debugger.js index 2c24917f62033..93736bfc75788 100644 --- a/src/mono/wasm/debugger/tests/debugger-test/runtime-debugger.js +++ b/src/mono/wasm/debugger/tests/debugger-test/runtime-debugger.js @@ -1,6 +1,8 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +"use strict"; + var Module = { config: null, diff --git a/src/mono/wasm/runtime-test.js b/src/mono/wasm/runtime-test.js index e4e7c88896bf0..76c02dfe63f85 100644 --- a/src/mono/wasm/runtime-test.js +++ b/src/mono/wasm/runtime-test.js @@ -1,7 +1,10 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. // -*- mode: js; js-indent-level: 4; -*- // // Run runtime tests under a JS shell or a browser // +"use strict"; //glue code to deal with the differences between chrome, ch, d8, jsc and sm. var is_browser = typeof window != "undefined"; @@ -13,9 +16,36 @@ if (typeof (console) === "undefined") { clear: function () { } }; } - globalThis.testConsole = console; +//define arguments for later +var allRuntimeArguments = null; +try { + 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)); + allRuntimeArguments = []; + for (let param of url.searchParams) { + if (param[0] == "arg") { + allRuntimeArguments.push(param[1]); + } + } + + } else if (typeof arguments !== "undefined" && typeof arguments !== "null") { + allRuntimeArguments = arguments; + } else if (typeof process !== 'undefined' && typeof process.argv !== "undefined") { + allRuntimeArguments = process.argv.slice(2); + } else if (typeof scriptArgs !== "undefined") { + allRuntimeArguments = scriptArgs; + } else if (typeof WScript !== "undefined" && WScript.Arguments) { + allRuntimeArguments = WScript.Arguments; + } else { + allRuntimeArguments = []; + } +} catch (e) { + console.log(e); +} + function proxyMethod (prefix, func, asJson) { return function() { const args = [...arguments]; @@ -66,15 +96,6 @@ 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); @@ -103,30 +124,8 @@ if (typeof performance == 'undefined') { } } -try { - if (typeof arguments == "undefined") - arguments = WScript.Arguments; - load = WScript.LoadScriptFile; - read = WScript.LoadBinaryFile; -} catch (e) { -} - -try { - if (typeof arguments == "undefined") { - if (typeof scriptArgs !== "undefined") - arguments = scriptArgs; - } -} catch (e) { -} - -if (arguments === undefined) - arguments = []; - //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) { // Notify the selenium script @@ -156,44 +155,42 @@ 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); +console.info("Arguments: " + allRuntimeArguments); +var profilers = []; +var setenv = {}; +var runtime_args = []; +var enable_gc = true; +var enable_zoneinfo = false; +var working_dir='/'; +while (allRuntimeArguments !== undefined && allRuntimeArguments.length > 0) { + if (allRuntimeArguments [0].startsWith ("--profile=")) { + var arg = allRuntimeArguments [0].substring ("--profile=".length); profilers.push (arg); - args = args.slice (1); - } else if (args [0].startsWith ("--setenv=")) { - var arg = args [0].substring ("--setenv=".length); + allRuntimeArguments = allRuntimeArguments.slice (1); + } else if (allRuntimeArguments [0].startsWith ("--setenv=")) { + var arg = allRuntimeArguments [0].substring ("--setenv=".length); var parts = arg.split ('='); - if (parts.length < 2) - fail_exec ("Error: malformed argument: '" + args [0]); - setenv [parts [0]] = arg.substring (parts [0].length + 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") { + if (parts.length != 2) + fail_exec ("Error: malformed argument: '" + allRuntimeArguments [0]); + setenv [parts [0]] = parts [1]; + allRuntimeArguments = allRuntimeArguments.slice (1); + } else if (allRuntimeArguments [0].startsWith ("--runtime-arg=")) { + var arg = allRuntimeArguments [0].substring ("--runtime-arg=".length); + runtime_args = allRuntimeArguments.push (arg); + allRuntimeArguments = allRuntimeArguments.slice (1); + } else if (allRuntimeArguments [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); + allRuntimeArguments = allRuntimeArguments.slice (1); + } else if (allRuntimeArguments [0].startsWith ("--working-dir=")) { + var arg = allRuntimeArguments [0].substring ("--working-dir=".length); working_dir = arg; - args = args.slice (1); + allRuntimeArguments = allRuntimeArguments.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(); @@ -316,17 +313,17 @@ var App = { init (""); } - if (args.length == 0) { + if (allRuntimeArguments.length == 0) { fail_exec ("Missing required --run argument"); return; } - if (args[0] == "--regression") { + if (allRuntimeArguments[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, allRuntimeArguments[1]); Module.print ("REGRESSION RESULT: " + res); } catch (e) { Module.print ("ABORT: " + e); @@ -343,23 +340,23 @@ var App = { if (runtime_args.length > 0) MONO.mono_wasm_set_runtime_options (runtime_args); - if (args[0] == "--run") { + if (allRuntimeArguments[0] == "--run") { // Run an exe - if (args.length == 1) { + if (allRuntimeArguments.length == 1) { fail_exec ("Error: Missing main executable argument."); return; } - main_assembly_name = args[1]; - var app_args = args.slice (2); + var main_assembly_name = allRuntimeArguments[1]; + var app_args = allRuntimeArguments.slice (2); - var main_argc = args.length - 2 + 1; + var main_argc = allRuntimeArguments.length - 2 + 1; var main_argv = Module._malloc (main_argc * 4); - aindex = 0; - Module.setValue (main_argv + (aindex * 4), wasm_strdup (args [1]), "i32") + var aindex = 0; + Module.setValue (main_argv + (aindex * 4), wasm_strdup (allRuntimeArguments [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 < allRuntimeArguments.length; ++i) { + Module.setValue (main_argv + (aindex * 4), wasm_strdup (allRuntimeArguments [i]), "i32"); aindex += 1; } wasm_set_main_args (main_argc, main_argv); @@ -381,7 +378,7 @@ var App = { } } else { - fail_exec ("Unhandled argument: " + args [0]); + fail_exec ("Unhandled argument: " + allRuntimeArguments [0]); } }, call_test_method: function (method_name, args, signature) { diff --git a/src/mono/wasm/runtime/binding_support.js b/src/mono/wasm/runtime/binding_support.js index 11d50bfc9558b..8d51dc8014e58 100644 --- a/src/mono/wasm/runtime/binding_support.js +++ b/src/mono/wasm/runtime/binding_support.js @@ -1,6 +1,8 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +"use strict"; + var BindingSupportLib = { $BINDING__postset: 'BINDING.export_functions (Module);', $BINDING: { @@ -776,6 +778,7 @@ var BindingSupportLib = { case typeof js_obj === "undefined": return 0; case typeof js_obj === "number": { + let result = null; if ((js_obj | 0) === js_obj) result = this._box_js_int (js_obj); else if ((js_obj >>> 0) === js_obj) @@ -1033,7 +1036,7 @@ var BindingSupportLib = { }, _create_named_function: function (name, argumentNames, body, closure) { - var result = null, keys = null, closureArgumentList = null, closureArgumentNames = null; + var result = null, closureArgumentList = null, closureArgumentNames = null; if (closure) { closureArgumentNames = Object.keys (closure); @@ -1135,7 +1138,7 @@ var BindingSupportLib = { var conv = primitiveConverters.get (key); if (!conv) - throw new Error ("Unknown parameter type " + type); + throw new Error ("Unknown parameter type " + key); var localStep = Object.create (conv.steps[0]); localStep.size = conv.size; @@ -1185,7 +1188,7 @@ var BindingSupportLib = { // worst-case allocation size instead of allocating dynamically, plus padding var bufferSizeBytes = converter.size + (args_marshal.length * 4) + 16; - var rootBufferSize = args_marshal.length; + // ensure the indirect values are 8-byte aligned so that aligned loads and stores will work var indirectBaseOffset = ((((args_marshal.length * 4) + 7) / 8) | 0) * 8; @@ -1286,7 +1289,7 @@ var BindingSupportLib = { body.push(");"); - bodyJs = body.join ("\r\n"); + var bodyJs = body.join ("\r\n"); try { compiledVariadicFunction = this._create_named_function("variadic_converter_" + converterName, argumentNames, bodyJs, closure); converter.compiled_variadic_function = compiledVariadicFunction; @@ -1473,10 +1476,10 @@ var BindingSupportLib = { ) { this._handle_exception_for_call (converter, buffer, resultRoot, exceptionRoot, argsRootBuffer); + let result = resultRoot.value; + if (is_result_marshaled) result = this._unbox_mono_obj_root (resultRoot); - else - result = resultRoot.value; this._teardown_after_call (converter, buffer, resultRoot, exceptionRoot, argsRootBuffer); return result; @@ -1615,7 +1618,7 @@ var BindingSupportLib = { "return result;" ); - bodyJs = body.join ("\r\n"); + var bodyJs = body.join ("\r\n"); if (friendly_name) { var escapeRE = /[^A-Za-z0-9_]/g; @@ -1865,7 +1868,6 @@ var BindingSupportLib = { js_obj[property] = js_value; result = true; } - } return BINDING._box_js_bool (result); } finally { diff --git a/src/mono/wasm/runtime/dotnet_support.js b/src/mono/wasm/runtime/dotnet_support.js index 3272b714eca90..f19328d9bfb3e 100644 --- a/src/mono/wasm/runtime/dotnet_support.js +++ b/src/mono/wasm/runtime/dotnet_support.js @@ -1,6 +1,8 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +"use strict"; + var DotNetSupportLib = { $DOTNET: { conv_string: function (mono_obj) { @@ -46,7 +48,7 @@ var DotNetSupportLib = { var funcNameJsString = DOTNET.conv_string(functionName); var argsJsonJsString = argsJson && DOTNET.conv_string (argsJson); - var dotNetExports = globaThis.DotNet; + var dotNetExports = globalThis.DotNet; if (!dotNetExports) { throw new Error('The Microsoft.JSInterop.js library is not loaded.'); } diff --git a/src/mono/wasm/runtime/library_mono.js b/src/mono/wasm/runtime/library_mono.js index 1e6fc31f047da..5364d44b21a2f 100644 --- a/src/mono/wasm/runtime/library_mono.js +++ b/src/mono/wasm/runtime/library_mono.js @@ -1,6 +1,8 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +"use strict"; + /** * @typedef WasmId * @type {object} @@ -50,26 +52,36 @@ var MonoSupportLib = { $MONO__postset: 'MONO.export_functions (Module);', $MONO: { + active_frames: [], pump_count: 0, timeout_queue: [], spread_timers_maximum:0, _vt_stack: [], mono_wasm_runtime_is_ready : false, mono_wasm_ignore_pdb_load_errors: true, + num_icu_assets_loaded_successfully: 0, + _async_method_objectId: 0, + _next_id_var: 0, + _next_call_function_res_id: 0, + _scratch_root_buffer: null, + _scratch_root_free_indices: null, + _scratch_root_free_indices_count: 0, + _scratch_root_free_instances: [], + _vt_stack: [], /** @type {object.} */ _id_table: {}, pump_message: function () { - if (!this.mono_background_exec) - this.mono_background_exec = Module.cwrap ("mono_background_exec", null); + if (!MONO.mono_background_exec) + MONO.mono_background_exec = Module.cwrap ("mono_background_exec", null); while (MONO.timeout_queue.length > 0) { --MONO.pump_count; MONO.timeout_queue.shift()(); } while (MONO.pump_count > 0) { --MONO.pump_count; - this.mono_background_exec (); + MONO.mono_background_exec (); } }, @@ -250,11 +262,6 @@ var MonoSupportLib = { } }, - _scratch_root_buffer: null, - _scratch_root_free_indices: null, - _scratch_root_free_indices_count: 0, - _scratch_root_free_instances: [], - _mono_wasm_root_prototype: { /** @returns {NativePointer} */ get_address: function () { @@ -300,20 +307,20 @@ var MonoSupportLib = { if (index === undefined) return; - this._scratch_root_buffer.set (index, 0); - this._scratch_root_free_indices[this._scratch_root_free_indices_count] = index; - this._scratch_root_free_indices_count++; + MONO._scratch_root_buffer.set (index, 0); + MONO._scratch_root_free_indices[MONO._scratch_root_free_indices_count] = index; + MONO._scratch_root_free_indices_count++; }, _mono_wasm_claim_scratch_index: function () { - if (!this._scratch_root_buffer) { + if (!MONO._scratch_root_buffer) { const maxScratchRoots = 8192; - this._scratch_root_buffer = this.mono_wasm_new_root_buffer (maxScratchRoots, "js roots"); + MONO._scratch_root_buffer = this.mono_wasm_new_root_buffer (maxScratchRoots, "js roots"); - this._scratch_root_free_indices = new Int32Array (maxScratchRoots); - this._scratch_root_free_indices_count = maxScratchRoots; + MONO._scratch_root_free_indices = new Int32Array (maxScratchRoots); + MONO._scratch_root_free_indices_count = maxScratchRoots; for (var i = 0; i < maxScratchRoots; i++) - this._scratch_root_free_indices[i] = maxScratchRoots - i - 1; + MONO._scratch_root_free_indices[i] = maxScratchRoots - i - 1; Object.defineProperty (this._mono_wasm_root_prototype, "value", { get: this._mono_wasm_root_prototype.get, @@ -322,11 +329,11 @@ var MonoSupportLib = { }); } - if (this._scratch_root_free_indices_count < 1) + if (MONO._scratch_root_free_indices_count < 1) throw new Error ("Out of scratch root space"); - var result = this._scratch_root_free_indices[this._scratch_root_free_indices_count - 1]; - this._scratch_root_free_indices_count--; + var result = MONO._scratch_root_free_indices[MONO._scratch_root_free_indices_count - 1]; + MONO._scratch_root_free_indices_count--; return result; }, @@ -423,11 +430,11 @@ var MonoSupportLib = { mono_wasm_new_root: function (value) { var result; - if (this._scratch_root_free_instances.length > 0) { - result = this._scratch_root_free_instances.pop (); + if (MONO._scratch_root_free_instances.length > 0) { + result = MONO._scratch_root_free_instances.pop (); } else { var index = this._mono_wasm_claim_scratch_index (); - var buffer = this._scratch_root_buffer; + var buffer = MONO._scratch_root_buffer; result = Object.create (this._mono_wasm_root_prototype); result.__buffer = buffer; @@ -488,7 +495,6 @@ var MonoSupportLib = { } }, - mono_text_decoder: undefined, string_decoder: { copy: function (mono_string) { if (mono_string === 0) @@ -677,7 +683,7 @@ var MonoSupportLib = { }, _cache_call_function_res: function (obj) { - const id = `dotnet:cfo_res:${this._next_call_function_res_id++}`; + const id = `dotnet:cfo_res:${MONO._next_call_function_res_id++}`; this._call_function_res_cache[id] = obj; return id; }, @@ -772,8 +778,8 @@ var MonoSupportLib = { }, _clear_per_step_state: function () { - this._next_id_var = 0; - this._id_table = {}; + MONO._next_id_var = 0; + MONO._id_table = {}; }, mono_wasm_debugger_resume: function () { @@ -823,11 +829,11 @@ var MonoSupportLib = { }, mono_wasm_runtime_ready: function () { - this.mono_wasm_runtime_is_ready = true; + MONO.mono_wasm_runtime_is_ready = true; this._clear_per_step_state (); // FIXME: where should this go? - this._next_call_function_res_id = 0; + MONO._next_call_function_res_id = 0; this._call_function_res_cache = {}; this._c_fn_table = {}; @@ -1109,15 +1115,13 @@ var MonoSupportLib = { return memoryOffset; }, - num_icu_assets_loaded_successfully: 0, - // @offset must be the address of an ICU data archive in the native heap. // returns true on success. mono_wasm_load_icu_data: function (offset) { var fn = Module.cwrap ('mono_wasm_load_icu_data', 'number', ['number']); var ok = (fn (offset)) === 1; if (ok) - this.num_icu_assets_loaded_successfully++; + MONO.num_icu_assets_loaded_successfully++; return ok; }, @@ -1320,7 +1324,7 @@ var MonoSupportLib = { invariantMode = true; if (!invariantMode) { - if (this.num_icu_assets_loaded_successfully > 0) { + if (MONO.num_icu_assets_loaded_successfully > 0) { console.debug ("MONO_WASM: ICU data archive(s) loaded, disabling invariant mode"); } else if (globalization_mode !== "icu") { console.debug ("MONO_WASM: ICU data archive(s) not loaded, using invariant globalization mode"); @@ -1378,7 +1382,7 @@ var MonoSupportLib = { var manifest; try { - manifestContent = Module.UTF8ArrayToString(data, 8, manifestSize); + var manifestContent = Module.UTF8ArrayToString(data, 8, manifestSize); manifest = JSON.parse(manifestContent); if (!(manifest instanceof Array)) return false; @@ -1405,7 +1409,7 @@ var MonoSupportLib = { Module['FS_createPath'](prefix, folder, true, true); }); - for (row of manifest) { + for (var row of manifest) { var name = row[0]; var length = row[1]; var bytes = data.slice(0, length); diff --git a/src/mono/wasm/wasm.proj b/src/mono/wasm/wasm.proj index 3eacc3e1307c1..372da1005bee2 100644 --- a/src/mono/wasm/wasm.proj +++ b/src/mono/wasm/wasm.proj @@ -70,6 +70,8 @@ <_EmccCommonFlags Include="-s "EXPORTED_FUNCTIONS=['_putchar']"" /> <_EmccCommonFlags Include="--source-map-base http://example.com" /> + <_EmccCommonFlags Include="-s STRICT_JS=1" /> + <_EmccCommonFlags Include="-s MODULARIZE=1" Condition="'$(WasmEnableES6)' != 'false'" /> <_EmccCommonFlags Include="-s EXPORT_ES6=1" Condition="'$(WasmEnableES6)' != 'false'" />