Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[wasm] improve startup #72275

Merged
merged 19 commits into from
Jul 26, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

export function log(message) {
// uncomment for debugging
console.log(message);
// console.log(message);
}

export function install() {
Expand Down
2 changes: 2 additions & 0 deletions src/mono/mono/component/mini-wasm-debugger.c
Original file line number Diff line number Diff line change
Expand Up @@ -375,6 +375,7 @@ mono_wasm_send_dbg_command_with_parms (int id, MdbgProtCommandSet command_set, i
gboolean result = FALSE;
MONO_ENTER_GC_UNSAFE;
if (!debugger_enabled) {
PRINT_ERROR_MSG ("DEBUGGING IS NOT ENABLED\n");
mono_wasm_add_dbg_command_received (0, id, 0, 0);
result = TRUE;
goto done;
Expand All @@ -401,6 +402,7 @@ mono_wasm_send_dbg_command (int id, MdbgProtCommandSet command_set, int command,
gboolean result = FALSE;
MONO_ENTER_GC_UNSAFE;
if (!debugger_enabled) {
PRINT_ERROR_MSG ("DEBUGGING IS NOT ENABLED\n");
mono_wasm_add_dbg_command_received(0, id, 0, 0);
result = TRUE;
goto done;
Expand Down
2 changes: 1 addition & 1 deletion src/mono/sample/wasm/Directory.Build.targets
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
<Exec Command="dotnet tool install -g dotnet-serve" IgnoreExitCode="true" />
</Target>
<Target Name="RunSampleWithBrowser" DependsOnTargets="BuildSampleInTree;CheckServe">
<Exec Command="$(_Dotnet) serve -o -d:bin/$(Configuration)/AppBundle -p:8000 --mime .mjs=text/javascript --mime .js=text/javascript --mime .cjs=text/javascript" IgnoreExitCode="true" YieldDuringToolExecution="true" />
<Exec Command="$(_Dotnet) serve -o -d:bin/$(Configuration)/AppBundle -p:8000 --mime .mjs=text/javascript --mime .js=text/javascript --mime .cjs=text/javascript -h Cross-Origin-Opener-Policy:same-origin -h Cross-Origin-Embedder-Policy:require-corp " IgnoreExitCode="true" YieldDuringToolExecution="true" />
</Target>
<Target Name="RunSampleWithBrowserAndSimpleServer" DependsOnTargets="BuildSampleInTree">
<Exec Command="$(_Dotnet) build -c $(Configuration) ..\simple-server\HttpServer.csproj" />
Expand Down
4 changes: 2 additions & 2 deletions src/mono/sample/wasm/browser/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ function sub(a, b) {

try {
const { MONO, RuntimeBuildInfo, IMPORTS } = await createDotnetRuntime(() => {
console.log('user code in createDotnetRuntime');
console.log('user code in createDotnetRuntime callback');
return {
configSrc: "./mono-config.json",
preInit: () => { console.log('user code Module.preInit'); },
Expand All @@ -31,7 +31,7 @@ try {
postRun: () => { console.log('user code Module.postRun'); },
}
});
console.log('after createDotnetRuntime');
console.log('user code after createDotnetRuntime()');
IMPORTS.Sample = {
Test: {
add,
Expand Down
18 changes: 9 additions & 9 deletions src/mono/wasm/debugger/DebuggerTestSuite/BreakpointTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ public async Task CreateJSBreakpoint()
{
// Test that js breakpoints get set correctly
// 13 24
// 13 53
// 14 24
var bp1_res = await SetBreakpoint("/debugger-driver.html", 13, 24);

Assert.EndsWith("debugger-driver.html", bp1_res.Value["breakpointId"].ToString());
Expand All @@ -52,23 +52,23 @@ public async Task CreateJSBreakpoint()
Assert.Equal(13, (int)loc["lineNumber"]);
Assert.Equal(24, (int)loc["columnNumber"]);

var bp2_res = await SetBreakpoint("/debugger-driver.html", 13, 53);
var bp2_res = await SetBreakpoint("/debugger-driver.html", 14, 24);

Assert.EndsWith("debugger-driver.html", bp2_res.Value["breakpointId"].ToString());
Assert.Equal(1, bp2_res.Value["locations"]?.Value<JArray>()?.Count);

var loc2 = bp2_res.Value["locations"]?.Value<JArray>()[0];

Assert.NotNull(loc2["scriptId"]);
Assert.Equal(13, (int)loc2["lineNumber"]);
Assert.Equal(53, (int)loc2["columnNumber"]);
Assert.Equal(14, (int)loc2["lineNumber"]);
Assert.Equal(24, (int)loc2["columnNumber"]);
}

[ConditionalFact(nameof(RunningOnChrome))]
public async Task CreateJS0Breakpoint()
{
// 13 24
// 13 53
// 14 24
var bp1_res = await SetBreakpoint("/debugger-driver.html", 13, 0);

Assert.EndsWith("debugger-driver.html", bp1_res.Value["breakpointId"].ToString());
Expand All @@ -78,18 +78,18 @@ public async Task CreateJS0Breakpoint()

Assert.NotNull(loc["scriptId"]);
Assert.Equal(13, (int)loc["lineNumber"]);
Assert.Equal(4, (int)loc["columnNumber"]);
Assert.Equal(24, (int)loc["columnNumber"]);

var bp2_res = await SetBreakpoint("/debugger-driver.html", 13, 53);
var bp2_res = await SetBreakpoint("/debugger-driver.html", 14, 0);

Assert.EndsWith("debugger-driver.html", bp2_res.Value["breakpointId"].ToString());
Assert.Equal(1, bp2_res.Value["locations"]?.Value<JArray>()?.Count);

var loc2 = bp2_res.Value["locations"]?.Value<JArray>()[0];

Assert.NotNull(loc2["scriptId"]);
Assert.Equal(13, (int)loc2["lineNumber"]);
Assert.Equal(53, (int)loc2["columnNumber"]);
Assert.Equal(14, (int)loc2["lineNumber"]);
Assert.Equal(24, (int)loc2["columnNumber"]);
}

[ConditionalTheory(nameof(RunningOnChrome))]
Expand Down
20 changes: 10 additions & 10 deletions src/mono/wasm/debugger/tests/debugger-test/debugger-driver.html
Original file line number Diff line number Diff line change
Expand Up @@ -7,30 +7,30 @@
var App = {
static_method_table: {},
init: function () {
this.int_add = getDotnetRuntime(0).INTERNAL.mono_bind_static_method ("[debugger-test] Math:IntAdd");
this.use_complex = getDotnetRuntime(0).INTERNAL.mono_bind_static_method ("[debugger-test] Math:UseComplex");
this.delegates_test = getDotnetRuntime(0).INTERNAL.mono_bind_static_method ("[debugger-test] Math:DelegatesTest");
this.generic_types_test = getDotnetRuntime(0).INTERNAL.mono_bind_static_method ("[debugger-test] Math:GenericTypesTest");
this.outer_method = getDotnetRuntime(0).INTERNAL.mono_bind_static_method ("[debugger-test] Math:OuterMethod");
this.async_method = getDotnetRuntime(0).INTERNAL.mono_bind_static_method ("[debugger-test] Math/NestedInMath:AsyncTest");
this.method_with_structs = getDotnetRuntime(0).INTERNAL.mono_bind_static_method ("[debugger-test] DebuggerTests.ValueTypesTest:MethodWithLocalStructs");
this.run_all = getDotnetRuntime(0).INTERNAL.mono_bind_static_method ("[debugger-test] DebuggerTest:run_all");
this.int_add = App.BINDING.bind_static_method("[debugger-test] Math:IntAdd");
this.use_complex = App.BINDING.bind_static_method("[debugger-test] Math:UseComplex");
this.delegates_test = App.BINDING.bind_static_method("[debugger-test] Math:DelegatesTest");
this.generic_types_test = App.BINDING.bind_static_method("[debugger-test] Math:GenericTypesTest");
this.outer_method = App.BINDING.bind_static_method("[debugger-test] Math:OuterMethod");
this.async_method = App.BINDING.bind_static_method("[debugger-test] Math/NestedInMath:AsyncTest");
this.method_with_structs = App.BINDING.bind_static_method("[debugger-test] DebuggerTests.ValueTypesTest:MethodWithLocalStructs");
this.run_all = App.BINDING.bind_static_method("[debugger-test] DebuggerTest:run_all");
this.static_method_table = {};
console.log ("ready");
},
};
function invoke_static_method (method_name, ...args) {
var method = App.static_method_table [method_name];
if (method == undefined)
method = App.static_method_table [method_name] = getDotnetRuntime(0).INTERNAL.mono_bind_static_method (method_name);
method = App.static_method_table[method_name] = App.BINDING.bind_static_method(method_name);

return method (...args);
}

async function invoke_static_method_async (method_name, ...args) {
var method = App.static_method_table [method_name];
if (method == undefined) {
method = App.static_method_table [method_name] = getDotnetRuntime(0).INTERNAL.mono_bind_static_method (method_name);
method = App.static_method_table[method_name] = App.BINDING.bind_static_method(method_name);
}

return await method (...args);
Expand Down
11 changes: 6 additions & 5 deletions src/mono/wasm/debugger/tests/debugger-test/debugger-main.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,22 +6,23 @@
import createDotnetRuntime from './dotnet.js'

try {
const { BINDING, INTERNAL } = await createDotnetRuntime(() => ({
const { BINDING } = await createDotnetRuntime(({ INTERNAL }) => ({
configSrc: "./mono-config.json",
onConfigLoaded: (config) => {
config.environment_variables["DOTNET_MODIFIABLE_ASSEMBLIES"] = "debug";
config.diagnostic_tracing = true;
/* For custom logging patch the functions below
config.diagnostic_tracing = true;
config.environment_variables["MONO_LOG_LEVEL"] = "debug";
config.environment_variables["MONO_LOG_MASK"] = "all";
INTERNAL.logging = {
trace: function (domain, log_level, message, isFatal, dataPtr) { },
debugger: function (level, message) { }
trace: (domain, log_level, message, isFatal, dataPtr) => console.log({ domain, log_level, message, isFatal, dataPtr }),
debugger: (level, message) => console.log({ level, message }),
};
*/
},
}));
App.init({ BINDING, INTERNAL })
App.BINDING = BINDING;
App.init()
} catch (err) {
console.log(`WASM ERROR ${err}`);
}
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
<EnableDefaultWasmAssembliesToBundle>false</EnableDefaultWasmAssembliesToBundle>
<WasmAppDir>$(AppDir)</WasmAppDir>
<WasmMainJSPath>debugger-main.js</WasmMainJSPath>
<!-- like is used on blazor -->
<!-- -1 enabled debugging and disables debug logging. -->
<WasmDebugLevel Condition="'$(WasmDebugLevel)'==''">-1</WasmDebugLevel>

<WasmResolveAssembliesBeforeBuild>true</WasmResolveAssembliesBeforeBuild>
Expand Down
1 change: 1 addition & 0 deletions src/mono/wasm/runtime/cjs/dotnet.cjs.extpost.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
var require = require || undefined;
var __dirname = __dirname || "";
// if loaded into global namespace and configured with global Module, we will self start in compatibility mode
const __isWorker = typeof globalThis.importScripts === "function";
let ENVIRONMENT_IS_GLOBAL = !__isWorker && (typeof globalThis.Module === "object" && globalThis.__dotnet_runtime === __dotnet_runtime);
Expand Down
17 changes: 12 additions & 5 deletions src/mono/wasm/runtime/cjs/dotnet.cjs.lib.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,23 +15,30 @@ const isPThread = `false`;
const DotnetSupportLib = {
$DOTNET: {},
// these lines will be placed early on emscripten runtime creation, passing import and export objects into __dotnet_runtime IFFE
// we replace implementation of readAsync and fetch
// we replace implementation of fetch
// replacement of require is there for consistency with ES6 code
$DOTNET__postset: `
let __dotnet_replacement_PThread = ${usePThreads} ? {} : undefined;
if (${usePThreads}) {
__dotnet_replacement_PThread.loadWasmModuleToWorker = PThread.loadWasmModuleToWorker;
__dotnet_replacement_PThread.threadInitTLS = PThread.threadInitTLS;
}
let __dotnet_replacements = {readAsync, fetch: globalThis.fetch, require, updateGlobalBufferAndViews, pthreadReplacements: __dotnet_replacement_PThread};
let __dotnet_replacements = {scriptUrl: undefined, fetch: globalThis.fetch, require, updateGlobalBufferAndViews, pthreadReplacements: __dotnet_replacement_PThread};
if (ENVIRONMENT_IS_NODE) {
__dotnet_replacements.requirePromise = Promise.resolve(require);
}
let __dotnet_exportedAPI = __dotnet_runtime.__initializeImportsAndExports(
{ isESM:false, isGlobal:ENVIRONMENT_IS_GLOBAL, isNode:ENVIRONMENT_IS_NODE, isWorker:ENVIRONMENT_IS_WORKER, isShell:ENVIRONMENT_IS_SHELL, isWeb:ENVIRONMENT_IS_WEB, isPThread:${isPThread}, locateFile, quit_, ExitStatus, requirePromise:Promise.resolve(require)},
{ isESM:false, isGlobal:ENVIRONMENT_IS_GLOBAL, isNode:ENVIRONMENT_IS_NODE, isWorker:ENVIRONMENT_IS_WORKER, isShell:ENVIRONMENT_IS_SHELL, isWeb:ENVIRONMENT_IS_WEB, isPThread:${isPThread}, quit_, ExitStatus, requirePromise:Promise.resolve(require)},
{ mono:MONO, binding:BINDING, internal:INTERNAL, module:Module, marshaled_exports: EXPORTS, marshaled_imports: IMPORTS },
__dotnet_replacements);
updateGlobalBufferAndViews = __dotnet_replacements.updateGlobalBufferAndViews;
readAsync = __dotnet_replacements.readAsync;
var fetch = __dotnet_replacements.fetch;
require = __dotnet_replacements.requireOut;
_scriptDir = __dirname = scriptDirectory = __dotnet_replacements.scriptDirectory;
if (ENVIRONMENT_IS_NODE) {
__dotnet_replacements.requirePromise.then(someRequire => {
require = someRequire;
});
}
var noExitRuntime = __dotnet_replacements.noExitRuntime;
if (${usePThreads}) {
PThread.loadWasmModuleToWorker = __dotnet_replacements.pthreadReplacements.loadWasmModuleToWorker;
Expand Down
5 changes: 4 additions & 1 deletion src/mono/wasm/runtime/cjs/dotnet.cjs.pre.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,13 @@ if (ENVIRONMENT_IS_GLOBAL) {
}
globalThis.Module.ready = Module.ready;
Module = createDotnetRuntime = globalThis.Module;
if (!createDotnetRuntime.locateFile) createDotnetRuntime.locateFile = createDotnetRuntime.__locateFile = (path) => scriptDirectory + path;
}
else if (typeof createDotnetRuntime === "object") {
Module = { ready: Module.ready, __undefinedConfig: Object.keys(createDotnetRuntime).length === 1 };
Object.assign(Module, createDotnetRuntime);
createDotnetRuntime = Module;
if (!createDotnetRuntime.locateFile) createDotnetRuntime.locateFile = createDotnetRuntime.__locateFile = (path) => scriptDirectory + path;
}
else if (typeof createDotnetRuntime === "function") {
Module = { ready: Module.ready };
Expand All @@ -19,7 +21,8 @@ else if (typeof createDotnetRuntime === "function") {
}
Object.assign(Module, extension);
createDotnetRuntime = Module;
if (!createDotnetRuntime.locateFile) createDotnetRuntime.locateFile = createDotnetRuntime.__locateFile = (path) => scriptDirectory + path;
}
else {
throw new Error("MONO_WASM: Can't locate global Module object or moduleFactory callback of createDotnetRuntime function.")
}
}
29 changes: 14 additions & 15 deletions src/mono/wasm/runtime/crypto-worker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ export function dotnet_browser_encrypt_decrypt(isEncrypting: boolean, key_buffer
}

if (result.length > output_len) {
console.error(`ENCRYPT DECRYPT: Encrypt/Decrypt length exceeds output length: ${result.length} > ${output_len}`);
console.error(`MONO_WASM_ENCRYPT_DECRYPT: Encrypt/Decrypt length exceeds output length: ${result.length} > ${output_len}`);
return ERR_ARGS;
}

Expand Down Expand Up @@ -91,7 +91,7 @@ function _send_simple_msg(msg: any, prefix: string, output_buffer: number, outpu
}

if (result.length > output_len) {
console.error(`${prefix}: Result length exceeds output length: ${result.length} > ${output_len}`);
console.error(`MONO_WASM_ENCRYPT_DECRYPT: ${prefix}: Result length exceeds output length: ${result.length} > ${output_len}`);
return ERR_ARGS;
}

Expand Down Expand Up @@ -132,7 +132,7 @@ function _send_msg_worker(msg: any): number | any {
const responseJson = JSON.parse(response);

if (responseJson.error !== undefined) {
console.error(`Worker failed with: ${responseJson.error}`);
console.error(`MONO_WASM_ENCRYPT_DECRYPT: Worker failed with: ${responseJson.error}`);
if (responseJson.error_type == "ArgumentsError")
return ERR_ARGS;
if (responseJson.error_type == "WorkerFailedError")
Expand All @@ -144,9 +144,9 @@ function _send_msg_worker(msg: any): number | any {
return responseJson.result;
} catch (err) {
if (err instanceof Error && err.stack !== undefined)
console.error(`${err.stack}`);
console.error(`MONO_WASM_ENCRYPT_DECRYPT: ${err.stack}`);
else
console.error(`_send_msg_worker failed: ${err}`);
console.error(`MONO_WASM_ENCRYPT_DECRYPT: _send_msg_worker failed: ${err}`);
return ERR_OP_FAILED;
}
}
Expand Down Expand Up @@ -202,10 +202,9 @@ class LibraryChannel {

public send_msg(msg: string): string {
try {
let state = Atomics.load(this.comm, this.STATE_IDX);
if (state !== this.STATE_IDLE)
console.log(`send_msg, waiting for idle now, ${state}`);
state = this.wait_for_state(pstate => pstate == this.STATE_IDLE, "waiting");
// const state = Atomics.load(this.comm, this.STATE_IDX);
// if (state !== this.STATE_IDLE) console.debug(`MONO_WASM_ENCRYPT_DECRYPT: send_msg, waiting for idle now, ${state}`);
this.wait_for_state(pstate => pstate == this.STATE_IDLE, "waiting");

this.send_request(msg);
return this.read_response();
Expand All @@ -214,14 +213,13 @@ class LibraryChannel {
throw err;
}
finally {
const state = Atomics.load(this.comm, this.STATE_IDX);
if (state !== this.STATE_IDLE)
console.log(`state at end of send_msg: ${state}`);
// const state = Atomics.load(this.comm, this.STATE_IDX);
// if (state !== this.STATE_IDLE) console.debug(`MONO_WASM_ENCRYPT_DECRYPT: state at end of send_msg: ${state}`);
}
}

public shutdown(): void {
console.debug("Shutting down crypto");
// console.debug("MONO_WASM_ENCRYPT_DECRYPT: Shutting down crypto");
const state = Atomics.load(this.comm, this.STATE_IDX);
if (state !== this.STATE_IDLE)
throw new Error(`OWNER: Invalid sync communication channel state: ${state}`);
Expand All @@ -232,14 +230,15 @@ class LibraryChannel {
Atomics.notify(this.comm, this.STATE_IDX);
}

// eslint-disable-next-line @typescript-eslint/no-unused-vars
private reset(reason: string): void {
console.debug(`reset: ${reason}`);
// console.debug(`MONO_WASM_ENCRYPT_DECRYPT: reset: ${reason}`);
const state = Atomics.load(this.comm, this.STATE_IDX);
if (state === this.STATE_SHUTDOWN)
return;

if (state === this.STATE_RESET || state === this.STATE_IDLE) {
console.debug(`state is already RESET or idle: ${state}`);
// console.debug(`MONO_WASM_ENCRYPT_DECRYPT: state is already RESET or idle: ${state}`);
return;
}

Expand Down