LibJS: Handle call stack limit exceptions in NewPromiseReactionJob

The promise job's fulfillment / rejection handlers may push an execution
context onto the VM, which will throw an internal error if our ad-hoc
call stack size limit has been reached. Thus, we cannot blindly VERIFY
that the result of invoking these handlers is non-abrupt.

This patch will propagate any internal error forward, and retains the
condition that any other error type is not thrown.
This commit is contained in:
Timothy Flynn 2025-02-03 21:41:35 -05:00 committed by Tim Flynn
parent b91a0f5403
commit 911b915763
Notes: github-actions[bot] 2025-02-05 13:06:00 +00:00
2 changed files with 13 additions and 1 deletions

View file

@ -58,7 +58,7 @@ static ThrowCompletionOr<Value> run_reaction_job(VM& vm, PromiseReaction& reacti
// f. If promiseCapability is undefined, then
if (promise_capability == nullptr) {
// i. Assert: handlerResult is not an abrupt completion.
VERIFY(!handler_result.is_abrupt());
MUST_OR_THROW_INTERNAL_ERROR(handler_result);
// ii. Return empty.
dbgln_if(PROMISE_DEBUG, "run_reaction_job: Reaction has no PromiseCapability, returning empty value");

View file

@ -18,4 +18,16 @@ test("infinite recursion", () => {
expect(() => {
new Proxy({}, { get: (_, __, p) => p.foo }).foo;
}).toThrowWithMessage(InternalError, "Call stack size limit exceeded");
expect(() => {
function outer() {
async function inner() {
await outer;
}
inner();
outer();
}
outer();
}).toThrowWithMessage(InternalError, "Call stack size limit exceeded");
});