summaryrefslogtreecommitdiff
path: root/js
diff options
context:
space:
mode:
Diffstat (limited to 'js')
-rw-r--r--js/timers.ts13
-rw-r--r--js/timers_test.ts9
2 files changed, 22 insertions, 0 deletions
diff --git a/js/timers.ts b/js/timers.ts
index 96bfc8c0f..9e9c312ee 100644
--- a/js/timers.ts
+++ b/js/timers.ts
@@ -25,6 +25,9 @@ interface Timer {
const EPOCH = Date.now();
const APOCALYPSE = 2 ** 32 - 2;
+// Timeout values > TIMEOUT_MAX are set to 1.
+const TIMEOUT_MAX = 2 ** 31 - 1;
+
let globalTimeoutDue: number | null = null;
let nextTimerId = 1;
@@ -50,6 +53,7 @@ function setGlobalTimeout(due: number | null, now: number) {
timeout = due - now;
assert(timeout >= 0);
}
+
// Send message to the backend.
const builder = flatbuffers.createBuilder();
msg.SetTimeout.startSetTimeout(builder);
@@ -181,7 +185,16 @@ function setTimer(
// and INT32_MAX. Any other value will cause the timer to fire immediately.
// We emulate this behavior.
const now = getTime();
+ if (delay > TIMEOUT_MAX) {
+ console.warn(
+ `${delay} does not fit into` +
+ " a 32-bit signed integer." +
+ "\nTimeout duration was set to 1."
+ );
+ delay = 1;
+ }
delay = Math.max(0, delay | 0);
+
// Create a new, unscheduled timer object.
const timer = {
id: nextTimerId++,
diff --git a/js/timers_test.ts b/js/timers_test.ts
index 1ea566c43..fe2ff64df 100644
--- a/js/timers_test.ts
+++ b/js/timers_test.ts
@@ -155,3 +155,12 @@ test(async function intervalCancelInvalidSilentFail() {
// Should silently fail (no panic)
clearInterval(2147483647);
});
+
+test(async function fireCallbackImmediatelyWhenDelayOverMaxValue() {
+ let count = 0;
+ setTimeout(() => {
+ count++;
+ }, 2 ** 31);
+ await waitForMs(1);
+ assertEqual(count, 1);
+});