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

Reply via email to