Skip to content

Commit 7980421

Browse files
authored
[browser] mono_exit improvements (#88387)
1 parent c93336a commit 7980421

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

64 files changed

+615
-241
lines changed

src/libraries/tests.proj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
<ProjectExclusions Include="$(MonoProjectRoot)sample\wasm\browser-webpack\Wasm.Browser.WebPack.Sample.csproj" />
4343
<ProjectExclusions Include="$(MonoProjectRoot)sample\wasm\node-webpack\Wasm.Node.WebPack.Sample.csproj" />
4444
<ProjectExclusions Include="$(MonoProjectRoot)sample\wasm\browser-nextjs\Wasm.Browser.NextJs.Sample.csproj" />
45+
<ProjectExclusions Include="$(MonoProjectRoot)sample\wasm\browser-shutdown\Wasm.Browser.Shutdown.Sample.csproj" />
4546

4647
<!-- These tests are completely disabled on wasm -->
4748
<ProjectExclusions Include="$(MSBuildThisFileDirectory)System.Text.RegularExpressions/tests/System.Text.RegularExpressions.Generators.Tests/System.Text.RegularExpressions.Generators.Tests.csproj" />
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
TOP=../../../../..
2+
3+
include ../wasm.mk
4+
5+
ifneq ($(AOT),)
6+
override MSBUILD_ARGS+=/p:RunAOTCompilation=true
7+
endif
8+
9+
PROJECT_NAME=Wasm.Browser.Shutdown.Sample.csproj
10+
11+
run: run-browser
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
4+
using System;
5+
using System.Runtime.InteropServices.JavaScript;
6+
using System.Runtime.InteropServices;
7+
8+
namespace Sample
9+
{
10+
public partial class Test
11+
{
12+
public static int Main(string[] args)
13+
{
14+
return 0;
15+
}
16+
17+
[JSExport()]
18+
public static void DoNothing ()
19+
{
20+
Console.WriteLine("You got it, boss! Doing nothing!");
21+
}
22+
23+
[JSExport()]
24+
public static void ThrowManagedException ()
25+
{
26+
throw new Exception("I'll make an exception to the rules just this once... and throw one.");
27+
}
28+
29+
[JSExport()]
30+
public static void CallFailFast ()
31+
{
32+
System.Environment.FailFast("User requested FailFast");
33+
}
34+
35+
[JSImport("timerTick", "main.js")]
36+
public static partial void TimerTick (int i);
37+
38+
[JSExport()]
39+
public static void StartTimer ()
40+
{
41+
int i = 0;
42+
var timer = new System.Timers.Timer(1000);
43+
timer.Elapsed += (s, e) => {
44+
TimerTick(i);
45+
i += 1;
46+
};
47+
timer.AutoReset = true;
48+
timer.Enabled = true;
49+
}
50+
}
51+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
<Import Project="..\DefaultBrowserSample.targets" />
3+
<ItemGroup>
4+
<WasmExtraFilesToDeploy Include="main.js" />
5+
</ItemGroup>
6+
</Project>
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<!DOCTYPE html>
2+
<!-- Licensed to the .NET Foundation under one or more agreements. -->
3+
<!-- The .NET Foundation licenses this file to you under the MIT license. -->
4+
<html>
5+
6+
<head>
7+
<title>Wasm Browser Shutdown Sample</title>
8+
<meta charset="UTF-8">
9+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
10+
<script type='module' src="./main.js"></script>
11+
</head>
12+
13+
<body>
14+
<h3 id="header">Wasm Browser Shutdown Sample</h3>
15+
<button id="throw-managed-exc">Throw Managed Exception</button>
16+
<button id="trigger-native-assert">Trigger Native Assert</button>
17+
<button id="trigger-failfast">Trigger Environment.FailFast</button>
18+
<button id="call-jsexport">Call Harmless JSExport</button>
19+
<button id="call-exit">Call exit</button>
20+
<button id="start-timer">Start Timer</button><br>
21+
Timer Value: <span id="timer-value"></span>
22+
</body>
23+
24+
</html>
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
4+
import { dotnet, exit } from './_framework/dotnet.js'
5+
6+
let exports = undefined,
7+
setenv = undefined;
8+
9+
window.addEventListener("load", onLoad);
10+
11+
try {
12+
const { setModuleImports, getAssemblyExports, setEnvironmentVariable, getConfig } = await dotnet
13+
.withModuleConfig()
14+
.withExitOnUnhandledError()
15+
.withExitCodeLogging()
16+
.withElementOnExit()
17+
.withAssertAfterExit()
18+
.withOnConfigLoaded(() => {
19+
// you can test abort of the startup by opening http://localhost:8000/?throwError=true
20+
const params = new URLSearchParams(location.search);
21+
if (params.get("throwError") === "true") {
22+
throw new Error("Error thrown from OnConfigLoaded");
23+
}
24+
})
25+
.create();
26+
27+
setModuleImports("main.js", {
28+
timerTick: (i) => {
29+
document.querySelector("#timer-value").textContent = i;
30+
},
31+
});
32+
33+
setenv = setEnvironmentVariable;
34+
const config = getConfig();
35+
exports = await getAssemblyExports(config.mainAssemblyName);
36+
}
37+
catch (err) {
38+
exit(2, err);
39+
}
40+
41+
function onLoad() {
42+
document.querySelector("#throw-managed-exc").addEventListener("click", () => {
43+
try {
44+
exports.Sample.Test.ThrowManagedException();
45+
alert("No JS exception was thrown!");
46+
} catch (exc) {
47+
alert(exc);
48+
}
49+
});
50+
document.querySelector("#trigger-failfast").addEventListener("click", () => {
51+
try {
52+
exports.Sample.Test.CallFailFast();
53+
alert("No JS exception was thrown!");
54+
} catch (exc) {
55+
alert(exc);
56+
}
57+
});
58+
document.querySelector("#start-timer").addEventListener("click", () => {
59+
try {
60+
exports.Sample.Test.StartTimer();
61+
} catch (exc) {
62+
alert(exc);
63+
}
64+
});
65+
document.querySelector("#trigger-native-assert").addEventListener("click", () => {
66+
try {
67+
setenv(null, null);
68+
alert("No JS exception was thrown!");
69+
} catch (exc) {
70+
alert(exc);
71+
}
72+
});
73+
document.querySelector("#call-jsexport").addEventListener("click", () => {
74+
try {
75+
exports.Sample.Test.DoNothing();
76+
} catch (exc) {
77+
alert(exc);
78+
}
79+
});
80+
document.querySelector("#call-exit").addEventListener("click", () => {
81+
try {
82+
exit(7, "User clicked exit");
83+
} catch (exc) {
84+
alert(exc);
85+
}
86+
});
87+
}

src/mono/sample/wasm/browser-threads-minimal/Program.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -277,7 +277,7 @@ public static async Task<string> FetchBackground(string url)
277277
Console.WriteLine($"smoke: FetchBackground 2 ManagedThreadId:{Thread.CurrentThread.ManagedThreadId}, SynchronizationContext: {SynchronizationContext.Current?.GetType().FullName ?? "null"}");
278278
var x = JSHost.ImportAsync(fetchhelper, "../fetchhelper.js");
279279
Console.WriteLine($"smoke: FetchBackground 3A ManagedThreadId:{Thread.CurrentThread.ManagedThreadId}, SynchronizationContext: {SynchronizationContext.Current?.GetType().FullName ?? "null"}");
280-
// using var import = await x.ConfigureAwait(false);
280+
using var import = await x;
281281
Console.WriteLine($"smoke: FetchBackground 3B ManagedThreadId:{Thread.CurrentThread.ManagedThreadId}, SynchronizationContext: {SynchronizationContext.Current?.GetType().FullName ?? "null"}");
282282
var r = await GlobalThisFetch(url);
283283
Console.WriteLine($"smoke: FetchBackground 4 ManagedThreadId:{Thread.CurrentThread.ManagedThreadId}, SynchronizationContext: {SynchronizationContext.Current?.GetType().FullName ?? "null"}");

src/mono/wasm/runtime/assets.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
import cwraps from "./cwraps";
55
import { mono_wasm_load_icu_data } from "./icu";
6-
import { ENVIRONMENT_IS_SHELL, ENVIRONMENT_IS_WEB, Module, loaderHelpers, runtimeHelpers } from "./globals";
6+
import { ENVIRONMENT_IS_SHELL, ENVIRONMENT_IS_WEB, Module, loaderHelpers, mono_assert, runtimeHelpers } from "./globals";
77
import { mono_log_info, mono_log_debug, mono_log_warn, parseSymbolMapFile } from "./logging";
88
import { mono_wasm_load_bytes_into_heap } from "./memory";
99
import { endMeasure, MeasuredBlock, startMeasure } from "./profiler";

src/mono/wasm/runtime/cancelable-promise.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
// The .NET Foundation licenses this file to you under the MIT license.
33

44
import { _lookup_js_owned_object } from "./gc-handles";
5-
import { createPromiseController, loaderHelpers } from "./globals";
5+
import { createPromiseController, loaderHelpers, mono_assert } from "./globals";
66
import { TaskCallbackHolder } from "./marshal-to-cs";
77
import { ControllablePromise, GCHandle } from "./types/internal";
88

src/mono/wasm/runtime/cwraps.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import type {
1212
import type { VoidPtr, CharPtrPtr, Int32Ptr, CharPtr, ManagedPointer } from "./types/emscripten";
1313
import { linkerDisableLegacyJsInterop, linkerEnableAotProfiler, linkerEnableBrowserProfiler, Module } from "./globals";
1414
import { mono_log_error } from "./logging";
15+
import { mono_assert } from "./globals";
1516

1617
type SigLine = [lazyOrSkip: boolean | (() => boolean), name: string, returnType: string | null, argTypes?: string[], opts?: any];
1718

@@ -76,6 +77,7 @@ const fn_signatures: SigLine[] = [
7677

7778
//INTERNAL
7879
[false, "mono_wasm_exit", "void", ["number"]],
80+
[false, "mono_wasm_abort", "void", []],
7981
[true, "mono_wasm_getenv", "number", ["string"]],
8082
[true, "mono_wasm_set_main_args", "void", ["number", "number"]],
8183
[false, "mono_wasm_enable_on_demand_gc", "void", ["number"]],
@@ -205,7 +207,8 @@ export interface t_Cwraps {
205207
mono_wasm_intern_string_ref(strRef: MonoStringRef): void;
206208

207209
//INTERNAL
208-
mono_wasm_exit(exit_code: number): number;
210+
mono_wasm_exit(exit_code: number): void;
211+
mono_wasm_abort(): void;
209212
mono_wasm_getenv(name: string): CharPtr;
210213
mono_wasm_enable_on_demand_gc(enable: number): void;
211214
mono_wasm_set_main_args(argc: number, argv: VoidPtr): void;

0 commit comments

Comments
 (0)