Skip to content

Issue #545 : yield across pcall or a Go call boundary raises the Lua 5.1 error - #548

Open
eldologuzzo wants to merge 1 commit into
yuin:masterfrom
eldologuzzo:fix-yield-across-pcall
Open

eldologuzzo wants to merge 1 commit into
yuin:masterfrom
eldologuzzo:fix-yield-across-pcall

Conversation

@eldologuzzo

Copy link
Copy Markdown

Fixes #545 .

Changes proposed in this pull request:

  • A coroutine that yielded from a Lua function called by Go code (pcall, xpcall, a table.sort comparator, any Go function calling Lua) unwound the nested main loop of that Go call. The next resume then crashed with a nil pointer dereference.
  • New LState.nCcalls: it counts the Go-to-Lua calls (callR) in progress on the thread, and PCall restores it when it recovers an error.
  • When a Go function returns -1 (yield) inside a coroutine while a nested call is in progress, it now raises attempt to yield across metamethod/C-call boundary. The enclosing pcall catches it and the coroutine keeps running, which is the Lua 5.1 behavior discussed in pcall doesn't work in conjection with coroutines. #45.
  • A yield at the top level of a coroutine is unchanged.
  • Edited _state.go and _vm.go; state.go and vm.go are regenerated with make build.
  • Tests in _glua-tests/coroutine.lua (yield inside pcall, inside a table.sort comparator, the coroutine continuing after the caught error, plain yields). On current master they fail.

🤖 Generated with Claude Code

…Lua 5.1 error

A coroutine that yielded from a Lua function called by Go code (pcall,
xpcall, table.sort, any Go function calling Lua) unwound the nested main
loop of that Go call, and the next resume dereferenced a nil frame.

LState.nCcalls counts the Go-to-Lua calls (callR) in progress on the
thread; PCall restores it when it recovers an error. A yield with a nested
call in progress raises "attempt to yield across metamethod/C-call
boundary", which the enclosing pcall catches, as in Lua 5.1.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Copilot AI balanced review requested due to automatic review settings October 7, 2026 21:22

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 Approval recommended

The counter remains balanced across normal and protected-error paths, and the tests cover the reported crash and preserved yield behavior.

0 open findings

What changed in this PR

Prevents coroutine yields from crossing non-resumable Go call boundaries, matching Lua 5.1 behavior and avoiding resume crashes.

Changes:

  • Tracks active Go-to-Lua calls and restores the counter after protected errors.
  • Raises the Lua 5.1 boundary error for invalid yields.
  • Adds regression coverage for pcall, table.sort, continuation, and normal yields.
File Description
_state.go Implements call-boundary tracking and recovery.
state.go Regenerated state implementation.
_vm.go Rejects invalid cross-boundary yields.
vm.go Regenerated VM implementation.
value.go Adds the per-thread call counter.
_glua-tests/​coroutine.lua Adds coroutine regression tests.

🧠 Review effort: Balanced


💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

coroutine.yield inside pcall crashes the next resume (nil pointer dereference)

2 participants