Skip to content

Commit 8d65009

Browse files
authored
Add MIN_NODE_VERSION setting (#18521)
This, along with #18465 (which run tests on the oldest supported version of node) should pave the way for us to update the emsdk version node to something a little more modern. See emscripten-core/emsdk#829 This first thing I do with this setting is use it do disable `NODEJS_CATCH_REJECTION` by default when we are targeting node 15 and above.
1 parent b4b6b8f commit 8d65009

File tree

6 files changed

+58
-26
lines changed

6 files changed

+58
-26
lines changed

.circleci/config.yml

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -553,17 +553,26 @@ jobs:
553553
- install-node-version:
554554
node_version: "10.19.0"
555555
- run-tests:
556-
title: "core2.test_hello_world"
557-
test_targets: "core2.test_hello_world"
556+
title: "selected subset"
557+
test_targets: "
558+
other.test_native_call_before_init
559+
other.test_node_unhandled_rejection
560+
core2.test_hello_world"
558561
# Run a few test with the most recent version of node
559562
# In particular we have some tests that require node flags on older
560563
# versions of node but not with the most recent version.
561564
- install-latest-node
562565
- run-tests:
563566
# Run tests that on older versions of node would require flags, but
564567
# those flags should not be injected on newer versions.
565-
title: "core2 subset"
566-
test_targets: "-v core2.test_pthread_create core2.test_i64_invoke_bigint core2.test_source_map core2.test_exceptions_wasm"
568+
title: "selected subset"
569+
test_targets: "-v
570+
other.test_native_call_before_init
571+
other.test_node_unhandled_rejection
572+
core2.test_pthread_create
573+
core2.test_i64_invoke_bigint
574+
core2.test_source_map
575+
core2.test_exceptions_wasm"
567576
- upload-test-results
568577
test-other:
569578
executor: bionic

emcc.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2157,10 +2157,20 @@ def phase_linker_setup(options, state, newargs):
21572157
settings.MIN_IE_VERSION = 0
21582158
settings.MIN_EDGE_VERSION = 0
21592159
settings.MIN_CHROME_VERSION = 0
2160+
settings.MIN_NODE_VERSION = 0
21602161

21612162
if settings.MIN_CHROME_VERSION <= 37:
21622163
settings.WORKAROUND_OLD_WEBGL_UNIFORM_UPLOAD_IGNORED_OFFSET_BUG = 1
21632164

2165+
# 10.19.0 is the oldest version of node that we do any testing with.
2166+
# Keep this in sync with the test-node-compat in .circleci/config.yml
2167+
# and MINIMUM_NODE_VERSION in tools/shared.py
2168+
if settings.MIN_NODE_VERSION:
2169+
if settings.MIN_NODE_VERSION < 101900:
2170+
exit_with_error('targeting node older than 10.19.00 is not supported')
2171+
if settings.MIN_NODE_VERSION >= 150000:
2172+
default_setting('NODEJS_CATCH_REJECTION', 0)
2173+
21642174
setup_environment_settings()
21652175

21662176
if options.use_closure_compiler != 0:

src/runtime_debug.js

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -39,13 +39,15 @@ function isExportedByForceFilesystem(name) {
3939
}
4040

4141
function missingGlobal(sym, msg) {
42-
Object.defineProperty(globalThis, sym, {
43-
configurable: true,
44-
get: function() {
45-
warnOnce('`' + sym + '` is not longer defined by emscripten. ' + msg);
46-
return undefined;
47-
}
48-
});
42+
if (typeof globalThis !== 'undefined') {
43+
Object.defineProperty(globalThis, sym, {
44+
configurable: true,
45+
get: function() {
46+
warnOnce('`' + sym + '` is not longer defined by emscripten. ' + msg);
47+
return undefined;
48+
}
49+
});
50+
}
4951
}
5052

5153
missingGlobal('buffer', 'Please use HEAP8.buffer or wasmMemory.buffer');

src/settings.js

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -725,21 +725,22 @@ var DISABLE_EXCEPTION_THROWING = false;
725725

726726
// By default we handle exit() in node, by catching the Exit exception. However,
727727
// this means we catch all process exceptions. If you disable this, then we no
728-
// longer do that, and exceptions work normally, which can be useful for libraries
729-
// or programs that don't need exit() to work.
730-
728+
// longer do that, and exceptions work normally, which can be useful for
729+
// libraries or programs that don't need exit() to work.
730+
//
731731
// Emscripten uses an ExitStatus exception to halt when exit() is called.
732732
// With this option, we prevent that from showing up as an unhandled
733733
// exception.
734734
// [link]
735735
var NODEJS_CATCH_EXIT = true;
736736

737-
// Catch unhandled rejections in node. Without this, node may print the error,
738-
// and that this behavior will change in future node, wait a few seconds, and
739-
// then exit with 0 (which hides the error if you don't read the log). With
740-
// this, we catch any unhandled rejection and throw an actual error, which will
741-
// make the process exit immediately with a non-0 return code.
742-
// This should be fixed in Node 15+.
737+
// Catch unhandled rejections in node. This only effect versions of node older
738+
// than 15. Without this, old version node will print a warning, but exit
739+
// with a zero return code. With this setting enabled, we handle any unhandled
740+
// rejection and throw an exception, which will cause the process exit
741+
// immediately with a non-0 return code.
742+
// This not needed in Node 15+ so this setting will default to false if
743+
// MIN_NODE_VERSION is 150000 or above.
743744
// [link]
744745
var NODEJS_CATCH_REJECTION = true;
745746

@@ -1785,6 +1786,12 @@ var MIN_EDGE_VERSION = 0x7FFFFFFF;
17851786
// [link]
17861787
var MIN_CHROME_VERSION = 75;
17871788

1789+
// Specifies minimum node version to target for the generated code. This is
1790+
// distinct from the minimum version required run the emscripten compiler.
1791+
// This version aligns with the current Ubuuntu TLS 20.04 (Focal).
1792+
// Version is encoded in MMmmVV, e.g. 1814101 denotes Node 18.14.01.
1793+
var MIN_NODE_VERSION = 101900;
1794+
17881795
// Tracks whether we are building with errno support enabled. Set to 0
17891796
// to disable compiling errno support in altogether. This saves a little
17901797
// bit of generated code size in applications that do not care about

src/shell.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -245,7 +245,10 @@ if (ENVIRONMENT_IS_NODE) {
245245
// not be needed with node v15 and about because it is now the default
246246
// behaviour:
247247
// See https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode
248-
process['on']('unhandledRejection', function(reason) { throw reason; });
248+
var nodeMajor = process.version.match(/^v(\d+)\./)[1];
249+
if (nodeMajor < 15) {
250+
process['on']('unhandledRejection', function(reason) { throw reason; });
251+
}
249252
#endif
250253

251254
quit_ = (status, toThrow) => {

test/test_other.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12032,18 +12032,19 @@ def test_node_unhandled_rejection(self):
1203212032
# exit code and log the stack trace correctly.
1203312033
self.run_process([EMCC, '--pre-js=pre.js', '-sNODEJS_CATCH_REJECTION', 'main.c'])
1203412034
output = self.run_js('a.out.js', assert_returncode=NON_ZERO)
12035+
self.assertContained('unhandledRejection', read_file('a.out.js'))
1203512036
self.assertContained('ReferenceError: missing is not defined', output)
1203612037
self.assertContained('at foo (', output)
1203712038

12038-
version = self.run_process(config.NODE_JS + ['--version'], stdout=PIPE).stdout.strip()
12039-
version = [int(v) for v in version.replace('v', '').replace('-pre', '').split('.')]
12040-
if version[0] >= 15:
12041-
self.skipTest('old behaviour of node JS cannot be tested on node v15 or above')
12042-
1204312039
# Without NODEJS_CATCH_REJECTION we expect node to log the unhandled rejection
1204412040
# but return 0.
1204512041
self.node_args = [a for a in self.node_args if '--unhandled-rejections' not in a]
1204612042
self.run_process([EMCC, '--pre-js=pre.js', '-sNODEJS_CATCH_REJECTION=0', 'main.c'])
12043+
self.assertNotContained('unhandledRejection', read_file('a.out.js'))
12044+
12045+
if shared.check_node_version()[0] >= 15:
12046+
self.skipTest('old behaviour of node JS cannot be tested on node v15 or above')
12047+
1204712048
output = self.run_js('a.out.js')
1204812049
self.assertContained('ReferenceError: missing is not defined', output)
1204912050
self.assertContained('at foo (', output)

0 commit comments

Comments
 (0)