From 47cae7de294532e6584a275acadda95d9cbb0a5a Mon Sep 17 00:00:00 2001 From: Sam Clegg Date: Tue, 7 Apr 2026 11:23:33 -0700 Subject: [PATCH] Remove `performance.now` hackery which only exists for node v18 + `DETERMINISTIC`. NFC I don't think its worth the extra complexity to support `DETERMINISTIC` on node v18 since that combination is likely extremely rare. (I don't know of any active users of `-sDETERMINISTIC` myself). --- src/deterministic.js | 1 - src/lib/libcore.js | 12 ++++++------ src/parseTools.mjs | 12 ------------ test/test_other.py | 2 ++ tools/link.py | 3 +++ 5 files changed, 11 insertions(+), 19 deletions(-) diff --git a/src/deterministic.js b/src/deterministic.js index 9c4b3ca5bd74f..4eef50459d111 100644 --- a/src/deterministic.js +++ b/src/deterministic.js @@ -20,7 +20,6 @@ Date.now = deterministicNow; // Note: this approach does not work on certain versions of Node.js // Specifically it seems like its not possible to override performance.now on // node v16 through v18. -// See getPerformanceNow in parseTools.mjs for how we deal with this. if (globalThis.performance) performance.now = deterministicNow; // for consistency between different builds than between runs of the same build diff --git a/src/lib/libcore.js b/src/lib/libcore.js index ee9cfcedef751..3857db9bd84fb 100644 --- a/src/lib/libcore.js +++ b/src/lib/libcore.js @@ -1355,13 +1355,13 @@ addToLibrary({ emscripten_date_now: () => Date.now(), - emscripten_performance_now: () => {{{ getPerformanceNow() }}}(), + emscripten_performance_now: () => performance.now(), #if PTHREADS && !AUDIO_WORKLET // Pthreads need their clocks synchronized to the execution of the main // thread, so, when using them, make sure to adjust all timings to the // respective time origins. - emscripten_get_now: () => performance.timeOrigin + {{{ getPerformanceNow() }}}(), + emscripten_get_now: () => performance.timeOrigin + performance.now(), #else #if AUDIO_WORKLET // https://github.com/WebAudio/web-audio-api/issues/2413 emscripten_get_now: `; @@ -1369,11 +1369,11 @@ addToLibrary({ // (https://github.com/WebAudio/web-audio-api/issues/2527), so if building // with // Audio Worklets enabled, do a dynamic check for its presence. - if (globalThis.performance && {{{ getPerformanceNow() }}}) { + if (globalThis.performance && performance.now) { #if PTHREADS - _emscripten_get_now = () => performance.timeOrigin + {{{ getPerformanceNow() }}}(); + _emscripten_get_now = () => performance.timeOrigin + performance.now(); #else - _emscripten_get_now = () => {{{ getPerformanceNow() }}}(); + _emscripten_get_now = () => performance.now(); #endif } else { _emscripten_get_now = Date.now; @@ -1383,7 +1383,7 @@ addToLibrary({ // Modern environment where performance.now() is supported: // N.B. a shorter form "_emscripten_get_now = performance.now;" is // unfortunately not allowed even in current browsers (e.g. FF Nightly 75). - emscripten_get_now: () => {{{ getPerformanceNow() }}}(), + emscripten_get_now: () => performance.now(), #endif #endif diff --git a/src/parseTools.mjs b/src/parseTools.mjs index 544d7bd808250..2b79bf12a31bf 100644 --- a/src/parseTools.mjs +++ b/src/parseTools.mjs @@ -1105,17 +1105,6 @@ function formattedMinNodeVersion() { return `v${major}.${minor}.${rev}`; } -function getPerformanceNow() { - // This is needed to support Node.js v16 - v18 where `performance.now` - // cannot be overridden in the normal way. - // TODO(sbc): remove this once we drop support for these versions. - if (DETERMINISTIC && ENVIRONMENT_MAY_BE_NODE) { - return 'deterministicNow'; - } else { - return 'performance.now'; - } -} - function ENVIRONMENT_IS_MAIN_THREAD() { return `(!${ENVIRONMENT_IS_WORKER_THREAD()})`; } @@ -1231,7 +1220,6 @@ addToCompileTimeContext({ getHeapForType, getHeapOffset, getNativeTypeSize, - getPerformanceNow, getUnsharedTextDecoderView, hasExportedSymbol, isSymbolNeeded, diff --git a/test/test_other.py b/test/test_other.py index 3ac05d902c1ee..dead08c617df6 100644 --- a/test/test_other.py +++ b/test/test_other.py @@ -12059,6 +12059,8 @@ def test_deterministic(self): printf("JS random: %d\n", EM_ASM_INT({ return Math.random() })); } ''') + if not self.try_require_node_version(19): + self.skipTest('-sDETERMINISTIC requires node v19 or above') self.run_process([EMCC, 'src.c', '-sDETERMINISTIC'] + self.get_cflags()) one = self.run_js('a.out.js') # ensure even if the time resolution is 1 second, that if we see the real diff --git a/tools/link.py b/tools/link.py index d4cab9999c9f2..10f0a4a48b295 100644 --- a/tools/link.py +++ b/tools/link.py @@ -1366,6 +1366,9 @@ def limit_incoming_module_api(): check_browser_versions() + if settings.DETERMINISTIC and settings.MIN_NODE_VERSION < 190000: + exit_with_error('DETERMINISTIC does not work with node < v19') + if settings.POLYFILL: # Emscripten requires certain ES6+ constructs by default in library code # - (various ES6 operators available in all browsers listed below)