Implement register-based closure ctx#1599
Conversation
|
Note The number of changes in this pull request is too large for Gemini Code Assist to generate a summary. |
Code Review SummaryThis is a well-designed implementation of register-based closure context passing. The 2-word ABI Strengths
Key Areas for Improvement
See inline comments for specific feedback. |
eece12d to
2a3a0b3
Compare
990544c to
2a799b2
Compare
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #1599 +/- ##
==========================================
- Coverage 91.00% 90.51% -0.49%
==========================================
Files 45 48 +3
Lines 11927 12120 +193
==========================================
+ Hits 10854 10971 +117
- Misses 898 958 +60
- Partials 175 191 +16 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
c663d3a to
dcc8fcc
Compare
This test is for issue goplus#1559, not goplus#1599. Generated with [codeagent](https://github.com/qbox/codeagent) Co-authored-by: luoliwoshang <51194195+luoliwoshang@users.noreply.github.com>
This test is for issue goplus#1559, not goplus#1599. Generated with [codeagent](https://github.com/qbox/codeagent) Co-authored-by: luoliwoshang <51194195+luoliwoshang@users.noreply.github.com>
Summary
This PR implements register‑based closure ctx passing while keeping LLGo’s 2‑word closure ABI
{fn, env}. On ctx‑register targets we write the ctx register and call the real symbol; on other targets we conditionally pass ctx as an implicit first parameter. Compared to PR #1568, the closure layout stays 2‑word (no inline env/hasCtx), so LLVM IR/snapshots change accordingly.ABI / Representation
envpoints to a context object containing captured fields, or isnilfor plain funcs.hasCtx;env == nilis the sole indicator.fnstores the real symbol, no wrapper stubs (__llgo_stub.*removed).fnpoints at the real method entry,envis the receiver/data pointer.Calling Convention
envas the first argument (receiver) and also write ctx for uniform semantics.env == nil:getClosurePtr
Context Register Mapping
-mno-80387-mfpmath=sse -msse2 -mno-80387Native builds reserve the ctx reg via clang target‑feature
+reserve-<reg>(arm64/riscv64/riscv32).x86/x86_64 use compiler flags to disable x87 so MM0 is not clobbered by
long doubleoperations.Example IR (closure + C func)
Example Go code:
With ctx register (arm64/riscv64/riscv32/amd64/386)
Caller (
main) writes ctx register and calls the real symbol (example uses arm64x26; x86 usesmm0withmovq/movdand a memory clobber):Closure body (
main$1) reads ctx register at entry:C function remains a normal symbol:
Without ctx register (wasm/arm)
Caller (
main) branches onenv == nil:Closure body (
main$1) takes an explicit ctx parameter:Discussion: Alternative Layout (difference only)
Alternative inline‑env layout (as in PR #1568):
Differences vs
{fn, env}(no value judgment):hasCtxis explicit; call sites branch on it instead ofenv == nil.Covered Scenarios
Plain funcs, captured closures, method values/expressions, interface method values, varargs,
go/defer, C callbacks.