Skip to content
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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