Skip to content

Commit

Permalink
Add MIN_NODE_VERSION setting (#18521)
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
sbc100 authored Jan 20, 2023
1 parent b4b6b8f commit 8d65009
Show file tree
Hide file tree
Showing 6 changed files with 58 additions and 26 deletions.
17 changes: 13 additions & 4 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -553,17 +553,26 @@ jobs:
- install-node-version:
node_version: "10.19.0"
- run-tests:
title: "core2.test_hello_world"
test_targets: "core2.test_hello_world"
title: "selected subset"
test_targets: "
other.test_native_call_before_init
other.test_node_unhandled_rejection
core2.test_hello_world"
# Run a few test with the most recent version of node
# In particular we have some tests that require node flags on older
# versions of node but not with the most recent version.
- install-latest-node
- run-tests:
# Run tests that on older versions of node would require flags, but
# those flags should not be injected on newer versions.
title: "core2 subset"
test_targets: "-v core2.test_pthread_create core2.test_i64_invoke_bigint core2.test_source_map core2.test_exceptions_wasm"
title: "selected subset"
test_targets: "-v
other.test_native_call_before_init
other.test_node_unhandled_rejection
core2.test_pthread_create
core2.test_i64_invoke_bigint
core2.test_source_map
core2.test_exceptions_wasm"
- upload-test-results
test-other:
executor: bionic
Expand Down
10 changes: 10 additions & 0 deletions emcc.py
Original file line number Diff line number Diff line change
Expand Up @@ -2157,10 +2157,20 @@ def phase_linker_setup(options, state, newargs):
settings.MIN_IE_VERSION = 0
settings.MIN_EDGE_VERSION = 0
settings.MIN_CHROME_VERSION = 0
settings.MIN_NODE_VERSION = 0

if settings.MIN_CHROME_VERSION <= 37:
settings.WORKAROUND_OLD_WEBGL_UNIFORM_UPLOAD_IGNORED_OFFSET_BUG = 1

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

setup_environment_settings()

if options.use_closure_compiler != 0:
Expand Down
16 changes: 9 additions & 7 deletions src/runtime_debug.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,13 +39,15 @@ function isExportedByForceFilesystem(name) {
}

function missingGlobal(sym, msg) {
Object.defineProperty(globalThis, sym, {
configurable: true,
get: function() {
warnOnce('`' + sym + '` is not longer defined by emscripten. ' + msg);
return undefined;
}
});
if (typeof globalThis !== 'undefined') {
Object.defineProperty(globalThis, sym, {
configurable: true,
get: function() {
warnOnce('`' + sym + '` is not longer defined by emscripten. ' + msg);
return undefined;
}
});
}
}

missingGlobal('buffer', 'Please use HEAP8.buffer or wasmMemory.buffer');
Expand Down
25 changes: 16 additions & 9 deletions src/settings.js
Original file line number Diff line number Diff line change
Expand Up @@ -725,21 +725,22 @@ var DISABLE_EXCEPTION_THROWING = false;

// By default we handle exit() in node, by catching the Exit exception. However,
// this means we catch all process exceptions. If you disable this, then we no
// longer do that, and exceptions work normally, which can be useful for libraries
// or programs that don't need exit() to work.

// longer do that, and exceptions work normally, which can be useful for
// libraries or programs that don't need exit() to work.
//
// Emscripten uses an ExitStatus exception to halt when exit() is called.
// With this option, we prevent that from showing up as an unhandled
// exception.
// [link]
var NODEJS_CATCH_EXIT = true;

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

Expand Down Expand Up @@ -1785,6 +1786,12 @@ var MIN_EDGE_VERSION = 0x7FFFFFFF;
// [link]
var MIN_CHROME_VERSION = 75;

// Specifies minimum node version to target for the generated code. This is
// distinct from the minimum version required run the emscripten compiler.
// This version aligns with the current Ubuuntu TLS 20.04 (Focal).
// Version is encoded in MMmmVV, e.g. 1814101 denotes Node 18.14.01.
var MIN_NODE_VERSION = 101900;

// Tracks whether we are building with errno support enabled. Set to 0
// to disable compiling errno support in altogether. This saves a little
// bit of generated code size in applications that do not care about
Expand Down
5 changes: 4 additions & 1 deletion src/shell.js
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,10 @@ if (ENVIRONMENT_IS_NODE) {
// not be needed with node v15 and about because it is now the default
// behaviour:
// See https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode
process['on']('unhandledRejection', function(reason) { throw reason; });
var nodeMajor = process.version.match(/^v(\d+)\./)[1];
if (nodeMajor < 15) {
process['on']('unhandledRejection', function(reason) { throw reason; });
}
#endif

quit_ = (status, toThrow) => {
Expand Down
11 changes: 6 additions & 5 deletions test/test_other.py
Original file line number Diff line number Diff line change
Expand Up @@ -12032,18 +12032,19 @@ def test_node_unhandled_rejection(self):
# exit code and log the stack trace correctly.
self.run_process([EMCC, '--pre-js=pre.js', '-sNODEJS_CATCH_REJECTION', 'main.c'])
output = self.run_js('a.out.js', assert_returncode=NON_ZERO)
self.assertContained('unhandledRejection', read_file('a.out.js'))
self.assertContained('ReferenceError: missing is not defined', output)
self.assertContained('at foo (', output)

version = self.run_process(config.NODE_JS + ['--version'], stdout=PIPE).stdout.strip()
version = [int(v) for v in version.replace('v', '').replace('-pre', '').split('.')]
if version[0] >= 15:
self.skipTest('old behaviour of node JS cannot be tested on node v15 or above')

# Without NODEJS_CATCH_REJECTION we expect node to log the unhandled rejection
# but return 0.
self.node_args = [a for a in self.node_args if '--unhandled-rejections' not in a]
self.run_process([EMCC, '--pre-js=pre.js', '-sNODEJS_CATCH_REJECTION=0', 'main.c'])
self.assertNotContained('unhandledRejection', read_file('a.out.js'))

if shared.check_node_version()[0] >= 15:
self.skipTest('old behaviour of node JS cannot be tested on node v15 or above')

output = self.run_js('a.out.js')
self.assertContained('ReferenceError: missing is not defined', output)
self.assertContained('at foo (', output)
Expand Down

0 comments on commit 8d65009

Please sign in to comment.