Skip to content

Commit 8395b84

Browse files
authored
Move ExitStatus and its dependencies to library functions. NFC (#17429)
1 parent 81948f0 commit 8395b84

29 files changed

+136
-135
lines changed

emcc.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1848,8 +1848,8 @@ def phase_linker_setup(options, state, newargs, user_settings):
18481848
if settings.CLOSURE_WARNINGS not in ['quiet', 'warn', 'error']:
18491849
exit_with_error('Invalid option -sCLOSURE_WARNINGS=%s specified! Allowed values are "quiet", "warn" or "error".' % settings.CLOSURE_WARNINGS)
18501850

1851-
if not settings.BOOTSTRAPPING_STRUCT_INFO:
1852-
if not settings.MINIMAL_RUNTIME:
1851+
if not settings.MINIMAL_RUNTIME:
1852+
if not settings.BOOTSTRAPPING_STRUCT_INFO:
18531853
if settings.DYNCALLS:
18541854
# Include dynCall() function by default in DYNCALLS builds in classic runtime; in MINIMAL_RUNTIME, must add this explicitly.
18551855
settings.DEFAULT_LIBRARY_FUNCS_TO_INCLUDE += ['$dynCall']
@@ -1860,8 +1860,10 @@ def phase_linker_setup(options, state, newargs, user_settings):
18601860

18611861
settings.DEFAULT_LIBRARY_FUNCS_TO_INCLUDE += ['$getValue', '$setValue']
18621862

1863-
if settings.SAFE_HEAP:
1864-
settings.DEFAULT_LIBRARY_FUNCS_TO_INCLUDE += ['$getValue_safe', '$setValue_safe']
1863+
settings.DEFAULT_LIBRARY_FUNCS_TO_INCLUDE += ['$ExitStatus']
1864+
1865+
if not settings.BOOTSTRAPPING_STRUCT_INFO and settings.SAFE_HEAP:
1866+
settings.DEFAULT_LIBRARY_FUNCS_TO_INCLUDE += ['$getValue_safe', '$setValue_safe']
18651867

18661868
if settings.MAIN_MODULE:
18671869
assert not settings.SIDE_MODULE

emscripten.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,8 @@ def update_settings_glue(wasm_file, metadata):
147147
assert '--enable-memory64' in settings.BINARYEN_FEATURES
148148

149149
settings.HAS_MAIN = bool(settings.MAIN_MODULE) or settings.PROXY_TO_PTHREAD or settings.STANDALONE_WASM or 'main' in settings.WASM_EXPORTS or '__main_argc_argv' in settings.WASM_EXPORTS
150+
if settings.HAS_MAIN and not settings.MINIMAL_RUNTIME:
151+
settings.DEFAULT_LIBRARY_FUNCS_TO_INCLUDE += ['$exitJS']
150152

151153
# When using dynamic linking the main function might be in a side module.
152154
# To be safe assume they do take input parametes.

src/library.js

Lines changed: 68 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -73,18 +73,72 @@ mergeInto(LibraryManager.library, {
7373
return cString;
7474
},
7575

76+
#if !MINIMAL_RUNTIME
77+
$exitJS__docs: '/** @param {boolean|number=} implicit */',
78+
$exitJS__deps: ['proc_exit'],
79+
$exitJS: function(status, implicit) {
80+
EXITSTATUS = status;
81+
82+
#if ASSERTIONS && !EXIT_RUNTIME
83+
checkUnflushedContent();
84+
#endif // ASSERTIONS && !EXIT_RUNTIME
85+
86+
#if USE_PTHREADS
87+
if (!implicit) {
88+
if (ENVIRONMENT_IS_PTHREAD) {
89+
#if PTHREADS_DEBUG
90+
err('Pthread 0x' + _pthread_self().toString(16) + ' called exit(), posting exitOnMainThread.');
91+
#endif
92+
// When running in a pthread we propagate the exit back to the main thread
93+
// where it can decide if the whole process should be shut down or not.
94+
// The pthread may have decided not to exit its own runtime, for example
95+
// because it runs a main loop, but that doesn't affect the main thread.
96+
exitOnMainThread(status);
97+
throw 'unwind';
98+
} else {
99+
#if PTHREADS_DEBUG
100+
#if EXIT_RUNTIME
101+
err('main thread called exit: keepRuntimeAlive=' + keepRuntimeAlive() + ' (counter=' + runtimeKeepaliveCounter + ')');
102+
#else
103+
err('main thread called exit: keepRuntimeAlive=' + keepRuntimeAlive());
104+
#endif
105+
#endif
106+
}
107+
}
108+
#endif
109+
110+
#if EXIT_RUNTIME
111+
if (!keepRuntimeAlive()) {
112+
exitRuntime();
113+
}
114+
#endif
115+
116+
#if ASSERTIONS
117+
// if exit() was called explicitly, warn the user if the runtime isn't actually being shut down
118+
if (keepRuntimeAlive() && !implicit) {
119+
#if !EXIT_RUNTIME
120+
var msg = 'program exited (with status: ' + status + '), but EXIT_RUNTIME is not set, so halting execution but not exiting the runtime or preventing further async execution (build with EXIT_RUNTIME=1, if you want a true shutdown)';
121+
#else
122+
var msg = 'program exited (with status: ' + status + '), but keepRuntimeAlive() is set (counter=' + runtimeKeepaliveCounter + ') due to an async operation, so halting execution but not exiting the runtime or preventing further async execution (you can use emscripten_force_exit, if you want to force a true shutdown)';
123+
#endif // EXIT_RUNTIME
124+
#if MODULARIZE
125+
readyPromiseReject(msg);
126+
#endif // MODULARIZE
127+
err(msg);
128+
}
129+
#endif // ASSERTIONS
130+
131+
_proc_exit(status);
132+
},
133+
#endif
134+
76135
exit__sig: 'vi',
77136
#if MINIMAL_RUNTIME
78137
// minimal runtime doesn't do any exit cleanup handling so just
79138
// map exit directly to the lower-level proc_exit syscall.
80139
exit: 'proc_exit',
81-
$exit: 'exit',
82140
#else
83-
exit: function(status) {
84-
// void _exit(int status);
85-
// http://pubs.opengroup.org/onlinepubs/000095399/functions/exit.html
86-
exit(status);
87-
},
141+
exit: '$exitJS',
88142
#endif
89143

90144
// Returns a pointer ('p'), which means an i32 on wasm32 and an i64 wasm64
@@ -3293,12 +3347,9 @@ mergeInto(LibraryManager.library, {
32933347
throw 'unwind';
32943348
},
32953349

3296-
emscripten_force_exit__deps: [
3350+
emscripten_force_exit__deps: ['exit',
32973351
#if !EXIT_RUNTIME && ASSERTIONS
32983352
'$warnOnce',
3299-
#endif
3300-
#if MINIMAL_RUNTIME
3301-
'exit',
33023353
#endif
33033354
],
33043355
emscripten_force_exit__proxy: 'sync',
@@ -3307,15 +3358,13 @@ mergeInto(LibraryManager.library, {
33073358
#if !EXIT_RUNTIME && ASSERTIONS
33083359
warnOnce('emscripten_force_exit cannot actually shut down the runtime, as the build does not have EXIT_RUNTIME set');
33093360
#endif
3310-
#if MINIMAL_RUNTIME
3311-
_exit(status);
3312-
#else
3361+
#if !MINIMAL_RUNTIME
33133362
noExitRuntime = false;
33143363
#if EXIT_RUNTIME
33153364
runtimeKeepaliveCounter = 0;
33163365
#endif
3317-
exit(status);
33183366
#endif
3367+
_exit(status);
33193368
},
33203369

33213370
_emscripten_out__sig: 'vi',
@@ -3338,13 +3387,13 @@ mergeInto(LibraryManager.library, {
33383387
// programs. This function is for implementing them.
33393388
_emscripten_get_progname__sig: 'vii',
33403389
_emscripten_get_progname: function(str, len) {
3341-
#if !MINIMAL_RUNTIME
3342-
#if ASSERTIONS
3390+
#if !MINIMAL_RUNTIME
3391+
#if ASSERTIONS
33433392
assert(typeof str == 'number');
33443393
assert(typeof len == 'number');
3345-
#endif
3394+
#endif
33463395
stringToUTF8(thisProgram, str, len);
3347-
#endif
3396+
#endif
33483397
},
33493398

33503399
emscripten_console_log__sig: 'vp',
@@ -3653,5 +3702,6 @@ DEFAULT_LIBRARY_FUNCS_TO_INCLUDE.push(
36533702
'$warnOnce',
36543703
'$ccall',
36553704
'$cwrap',
3705+
'$ExitStatus',
36563706
);
36573707
#endif

src/library_bootstrap.js

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,20 @@ assert(Object.keys(LibraryManager.library).length === 0);
1515
mergeInto(LibraryManager.library, {
1616
$callRuntimeCallbacks: function() {},
1717

18+
$ExitStatus__docs: '/** @constructor */',
19+
$ExitStatus: function(status) {
20+
this.name = 'ExitStatus';
21+
this.message = 'Program terminated with exit(' + status + ')';
22+
this.status = status;
23+
},
24+
25+
$exitJS__deps: ['$ExitStatus'],
26+
$exitJS: function(code) {
27+
quit_(code, new ExitStatus(code));
28+
},
29+
1830
$handleException: function(e) {
19-
if (!(e instanceof ExitStatus) && e !== 'unwind') {
31+
if (e !== 'unwind') {
2032
throw e;
2133
}
2234
},

src/library_syscall.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1043,7 +1043,7 @@ function wrapSyscallFunction(x, library, isWasi) {
10431043
pre += "var canWarn = true;\n";
10441044
pre += "var ret = (function() {\n";
10451045
post += "})();\n";
1046-
post += "if (ret < 0 && canWarn) {\n";
1046+
post += "if (ret && ret < 0 && canWarn) {\n";
10471047
post += " err('error: syscall may have failed with ' + (-ret) + ' (' + ERRNO_MESSAGES[-ret] + ')');\n";
10481048
post += "}\n";
10491049
post += "err('syscall return: ' + ret);\n";

src/library_wasi.js

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,36 @@
55
*/
66

77
var WasiLibrary = {
8+
#if !MINIMAL_RUNTIME
9+
$ExitStatus__docs: '/** @constructor */',
10+
$ExitStatus: function(status) {
11+
this.name = 'ExitStatus';
12+
this.message = 'Program terminated with exit(' + status + ')';
13+
this.status = status;
14+
},
15+
proc_exit__deps: ['$ExitStatus'],
16+
#endif
17+
818
proc_exit__nothrow: true,
919
proc_exit__sig: 'vi',
1020
proc_exit: function(code) {
1121
#if MINIMAL_RUNTIME
1222
throw 'exit(' + code + ')';
1323
#else
14-
procExit(code);
24+
#if RUNTIME_DEBUG
25+
err('proc_exit: ' + code);
26+
#endif
27+
EXITSTATUS = code;
28+
if (!keepRuntimeAlive()) {
29+
#if USE_PTHREADS
30+
PThread.terminateAllThreads();
31+
#endif
32+
#if expectToReceiveOnModule('onExit')
33+
if (Module['onExit']) Module['onExit'](code);
34+
#endif
35+
ABORT = true;
36+
}
37+
quit_(code, new ExitStatus(code));
1538
#endif
1639
},
1740

src/modules.js

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -407,11 +407,6 @@ function exportRuntime() {
407407
runtimeElements.push('WasmSourceMap');
408408
}
409409

410-
if (!MINIMAL_RUNTIME) {
411-
// Symbols that only exist in the regular runtime.
412-
runtimeElements.push('ExitStatus');
413-
}
414-
415410
if (STACK_OVERFLOW_CHECK) {
416411
runtimeElements.push('writeStackCookie');
417412
runtimeElements.push('checkStackCookie');

src/postamble.js

Lines changed: 1 addition & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -92,16 +92,6 @@ function runMemoryInitializer() {
9292

9393
var calledRun;
9494

95-
/**
96-
* @constructor
97-
* @this {ExitStatus}
98-
*/
99-
function ExitStatus(status) {
100-
this.name = "ExitStatus";
101-
this.message = "Program terminated with exit(" + status + ")";
102-
this.status = status;
103-
}
104-
10595
var calledMain = false;
10696

10797
#if STANDALONE_WASM && MAIN_READS_PARAMS
@@ -192,7 +182,7 @@ function callMain(args) {
192182
#endif
193183
#else
194184
// if we're not running an evented main loop, it's time to exit
195-
exit(ret, /* implicit = */ true);
185+
exitJS(ret, /* implicit = */ true);
196186
return ret;
197187
}
198188
catch (e) {
@@ -408,79 +398,6 @@ function checkUnflushedContent() {
408398
#endif // EXIT_RUNTIME
409399
#endif // ASSERTIONS
410400

411-
/** @param {boolean|number=} implicit */
412-
function exit(status, implicit) {
413-
EXITSTATUS = status;
414-
415-
#if ASSERTIONS && !EXIT_RUNTIME
416-
checkUnflushedContent();
417-
#endif // ASSERTIONS && !EXIT_RUNTIME
418-
419-
#if USE_PTHREADS
420-
if (!implicit) {
421-
if (ENVIRONMENT_IS_PTHREAD) {
422-
#if PTHREADS_DEBUG
423-
err('Pthread 0x' + _pthread_self().toString(16) + ' called exit(), posting exitOnMainThread.');
424-
#endif
425-
// When running in a pthread we propagate the exit back to the main thread
426-
// where it can decide if the whole process should be shut down or not.
427-
// The pthread may have decided not to exit its own runtime, for example
428-
// because it runs a main loop, but that doesn't affect the main thread.
429-
exitOnMainThread(status);
430-
throw 'unwind';
431-
} else {
432-
#if PTHREADS_DEBUG
433-
#if EXIT_RUNTIME
434-
err('main thread called exit: keepRuntimeAlive=' + keepRuntimeAlive() + ' (counter=' + runtimeKeepaliveCounter + ')');
435-
#else
436-
err('main thread called exit: keepRuntimeAlive=' + keepRuntimeAlive());
437-
#endif
438-
#endif
439-
}
440-
}
441-
#endif
442-
443-
#if EXIT_RUNTIME
444-
if (!keepRuntimeAlive()) {
445-
exitRuntime();
446-
}
447-
#endif
448-
449-
#if ASSERTIONS
450-
// if exit() was called explicitly, warn the user if the runtime isn't actually being shut down
451-
if (keepRuntimeAlive() && !implicit) {
452-
#if !EXIT_RUNTIME
453-
var msg = 'program exited (with status: ' + status + '), but EXIT_RUNTIME is not set, so halting execution but not exiting the runtime or preventing further async execution (build with EXIT_RUNTIME=1, if you want a true shutdown)';
454-
#else
455-
var msg = 'program exited (with status: ' + status + '), but keepRuntimeAlive() is set (counter=' + runtimeKeepaliveCounter + ') due to an async operation, so halting execution but not exiting the runtime or preventing further async execution (you can use emscripten_force_exit, if you want to force a true shutdown)';
456-
#endif // EXIT_RUNTIME
457-
#if MODULARIZE
458-
readyPromiseReject(msg);
459-
#endif // MODULARIZE
460-
err(msg);
461-
}
462-
#endif // ASSERTIONS
463-
464-
procExit(status);
465-
}
466-
467-
function procExit(code) {
468-
#if RUNTIME_DEBUG
469-
err('procExit: ' + code);
470-
#endif
471-
EXITSTATUS = code;
472-
if (!keepRuntimeAlive()) {
473-
#if USE_PTHREADS
474-
PThread.terminateAllThreads();
475-
#endif
476-
#if expectToReceiveOnModule('onExit')
477-
if (Module['onExit']) Module['onExit'](code);
478-
#endif
479-
ABORT = true;
480-
}
481-
quit_(code, new ExitStatus(code));
482-
}
483-
484401
#if expectToReceiveOnModule('preInit')
485402
if (Module['preInit']) {
486403
if (typeof Module['preInit'] == 'function') Module['preInit'] = [Module['preInit']];
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
31595
1+
31596
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
31695
1+
31696

0 commit comments

Comments
 (0)