1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-31 10:38:11 +00:00

LibJS: Save scheduled jumps when entering unwind contexts

These are then restored upon `ContinuePendingUnwind`.
This stops us from forgetting where we needed to jump when we do extra
try-catches in finally blocks.

Co-Authored-By: Jesús "gsus" Lapastora <cyber.gsuscode@gmail.com>
This commit is contained in:
Hendiadyoin1 2023-10-21 22:46:40 +02:00 committed by Andreas Kling
parent 4da5b8ec67
commit 1341f4438d
4 changed files with 95 additions and 2 deletions

View file

@ -361,3 +361,88 @@ test("Throw while breaking", () => {
expect(executionOrder).toEqual([1, 2, 3]);
});
test("Throw while breaking with nested try-catch in finalizer", () => {
const executionOrder = [];
try {
for (const i = 1337; ; expect().fail("Jumped to for loop update block")) {
try {
executionOrder.push(1);
break;
} finally {
try {
throw 1;
} catch {
executionOrder.push(2);
}
executionOrder.push(3);
}
expect().fail("Jumped out of inner finally statement");
}
} finally {
executionOrder.push(4);
}
expect(() => {
i;
}).toThrowWithMessage(ReferenceError, "'i' is not defined");
expect(executionOrder).toEqual([1, 2, 3, 4]);
});
test("Throw while breaking with nested try-catch-finally in finalizer", () => {
const executionOrder = [];
try {
for (const i = 1337; ; expect().fail("Jumped to for loop update block")) {
try {
executionOrder.push(1);
break;
} finally {
try {
executionOrder.push(2);
} catch {
expect.fail("Entered catch");
} finally {
executionOrder.push(3);
}
executionOrder.push(4);
}
expect().fail("Jumped out of inner finally statement");
}
} finally {
executionOrder.push(5);
}
expect(() => {
i;
}).toThrowWithMessage(ReferenceError, "'i' is not defined");
expect(executionOrder).toEqual([1, 2, 3, 4, 5]);
});
test("Throw while breaking with nested try-catch-finally with throw in finalizer", () => {
const executionOrder = [];
try {
for (const i = 1337; ; expect().fail("Jumped to for loop update block")) {
try {
executionOrder.push(1);
break;
} finally {
try {
throw 1;
} catch {
executionOrder.push(2);
} finally {
executionOrder.push(3);
}
executionOrder.push(4);
}
expect().fail("Jumped out of inner finally statement");
}
} finally {
executionOrder.push(5);
}
expect(() => {
i;
}).toThrowWithMessage(ReferenceError, "'i' is not defined");
expect(executionOrder).toEqual([1, 2, 3, 4, 5]);
});