Branch: refs/heads/main
Home: https://github.com/WebKit/WebKit
Commit: 4fa7b55ae4c6485fcdef946f98b692bff1a2fcc6
https://github.com/WebKit/WebKit/commit/4fa7b55ae4c6485fcdef946f98b692bff1a2fcc6
Author: Yusuke Suzuki <[email protected]>
Date: 2026-09-08 (Tue, 08 Sep 2026)
Changed paths:
A JSTests/stress/no-tail-call-in-generator-and-async-function-bodies.js
A JSTests/stress/tail-call-eval-identifier-resolving-to-non-eval-function.js
M JSTests/test262/expectations-linux.yaml
M JSTests/test262/expectations.yaml
M Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp
M Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h
M Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp
Log Message:
-----------
[JSC] eval call should recognize tail-position
https://bugs.webkit.org/show_bug.cgi?id=323597
rdar://186840477
Reviewed by Sosuke Suzuki.
This patch fixes TCO for function call named "eval".
We follow to the pattern used in spread call case: performing CallDirectEval
only when the function is actually eval function. Otherwise, do a tail-call.
Doing so uncovered a separate bug in how we decide what a tail position is.
Generator, async function, and async generator bodies hold no tail positions
at all (IsInTailPosition steps 4 to 7), but BytecodeGenerator enabled TCO in
them anyway. An async generator awaits the value its body returns, so
op_tail_call jumped over that await and resolved the iterator result with the
promise itself; the other body modes dropped a frame that has to stay on the
stack. This is not specific to the new eval path, an ordinary call hits it too:
async function* g() { "use strict"; return Promise.resolve(42); }
g().next() // resolved with { value: <promise>, done: true }
So exclude those parse modes when computing m_allowTailCallOptimization.
Tests: JSTests/stress/no-tail-call-in-generator-and-async-function-bodies.js
JSTests/stress/tail-call-eval-identifier-resolving-to-non-eval-function.js
* JSTests/stress/no-tail-call-in-generator-and-async-function-bodies.js: Added.
(shouldBe):
(drain):
(asyncGeneratorAwaitsReturnedCall.f):
(asyncGeneratorAwaitsReturnedCall.async plainCall):
(asyncGeneratorAwaitsReturnedCall.async memberCall):
(asyncGeneratorAwaitsReturnedCall.async spreadCall):
(asyncGeneratorAwaitsReturnedCall.async applyCall):
(asyncGeneratorAwaitsReturnedCall):
(bodiesKeepTheirFrame.callerName):
(bodiesKeepTheirFrame.generatorBody):
(bodiesKeepTheirFrame.async asyncFunctionBody):
(bodiesKeepTheirFrame.async asyncGeneratorBody):
(bodiesKeepTheirFrame.ordinaryStrictFunction):
(bodiesKeepTheirFrame):
* JSTests/stress/tail-call-eval-identifier-resolving-to-non-eval-function.js:
Added.
(shouldBe):
(functionScope.f):
(functionScopeDynamic.f):
(functionScopeDynamic):
(withScope.with.f):
(withScope):
(spreadArguments.f):
(spreadArguments):
(realDirectEvalInTailPosition.f):
(realDirectEvalInTailPosition):
(asyncGeneratorScope.eval):
(asyncGeneratorScope.async g):
(asyncGeneratorScope):
(globalF):
* JSTests/test262/expectations-linux.yaml:
* JSTests/test262/expectations.yaml:
* Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp:
(JSC::BytecodeGenerator::BytecodeGenerator):
* Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h:
(JSC::BytecodeGenerator::allowsTailCallOptimization const):
* Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp:
(JSC::EvalFunctionCallNode::emitBytecode):
Canonical link: https://commits.webkit.org/320687@main
To unsubscribe from these emails, change your notification settings at
https://github.com/WebKit/WebKit/settings/notifications