Add pyframe functions to c-api#8215
Conversation
📝 WalkthroughWalkthroughAdds a new public ChangesPyFrame FFI Module
Estimated code review effort: 2 (Simple) | ~10 minutes Sequence Diagram(s)sequenceDiagram
participant Caller
participant PyFrameAPI as PyFrame FFI
participant VM as with_vm
participant Frame
Caller->>PyFrameAPI: PyFrame_GetCode(frame)
PyFrameAPI->>VM: with_vm(downcast to Frame)
VM->>Frame: try_downcast_ref
Frame-->>VM: code object
VM-->>PyFrameAPI: *mut PyObject
PyFrameAPI-->>Caller: return code pointer
Caller->>PyFrameAPI: PyFrame_GetLineNumber(frame)
PyFrameAPI->>VM: with_vm(downcast to Frame)
VM->>Frame: try_downcast_ref
Frame-->>VM: line number
VM-->>PyFrameAPI: c_int
PyFrameAPI-->>Caller: return line number
Suggested reviewers: 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
🧹 Nitpick comments (2)
crates/capi/src/pyframe.rs (2)
6-11: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winReuse
Frame::f_code()instead of touching the field directly.
crates/vm/src/builtins/frame.rsalready exposes a public accessor for this: The Framef_codeaccessor returnsself.code.clone(). Callingframe.f_code()here avoids depending on thecodefield's visibility/shape directly from another crate and keeps a single source of truth if the accessor logic ever changes.♻️ Proposed refactor
with_vm(|vm| { let frame = unsafe { &*frame }.try_downcast_ref::<Frame>(vm)?; - Ok(frame.code.clone()) + Ok(frame.f_code()) })🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@crates/capi/src/pyframe.rs` around lines 6 - 11, Refactor PyFrame_GetCode to use the public Frame::f_code() accessor instead of cloning frame.code directly. In the PyFrame_GetCode function, keep the existing try_downcast_ref::<Frame>(vm) lookup, then call frame.f_code() to obtain the code object so this crate depends on the accessor rather than the Frame field layout. This keeps the implementation aligned with the Frame API in builtins::frame::Frame and preserves a single source of truth for code retrieval.
14-24: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winDuplicated line-number logic — reuse
Frame::f_lineno().This re-implements the exact branching already defined publicly on
Frame:f_linenoselectsfirst_line_numberwhenlasti()==0, otherwise usescurrent_location().line.get(). Thelasti()==0guard exists specifically to avoid an underflow incurrent_location()'slocations[self.lasti()-1]indexing — duplicating this here risks silent divergence if that VM-side logic is ever changed (e.g. bug fix, edge-case handling) without updating this copy.♻️ Proposed refactor
with_vm(|vm| { let frame = unsafe { &*frame }.try_downcast_ref::<Frame>(vm)?; - let lineno = if frame.lasti() == 0 { - frame.code.first_line_number.map_or(1, |n| n.get()) - } else { - frame.current_location().line.get() - }; - Ok(lineno as core::ffi::c_int) + Ok(frame.f_lineno() as core::ffi::c_int) })🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@crates/capi/src/pyframe.rs` around lines 14 - 24, Replace the duplicated line-number branching in PyFrame_GetLineNumber with the existing Frame::f_lineno() logic instead of re-implementing the lasti()/first_line_number/current_location() check here. Keep the unsafe frame cast and VM lookup in PyFrame_GetLineNumber, but delegate the actual line-number retrieval to Frame::f_lineno() so this C API entry point stays consistent with the Frame method and won’t drift if the VM-side behavior changes.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In `@crates/capi/src/pyframe.rs`:
- Around line 6-11: Refactor PyFrame_GetCode to use the public Frame::f_code()
accessor instead of cloning frame.code directly. In the PyFrame_GetCode
function, keep the existing try_downcast_ref::<Frame>(vm) lookup, then call
frame.f_code() to obtain the code object so this crate depends on the accessor
rather than the Frame field layout. This keeps the implementation aligned with
the Frame API in builtins::frame::Frame and preserves a single source of truth
for code retrieval.
- Around line 14-24: Replace the duplicated line-number branching in
PyFrame_GetLineNumber with the existing Frame::f_lineno() logic instead of
re-implementing the lasti()/first_line_number/current_location() check here.
Keep the unsafe frame cast and VM lookup in PyFrame_GetLineNumber, but delegate
the actual line-number retrieval to Frame::f_lineno() so this C API entry point
stays consistent with the Frame method and won’t drift if the VM-side behavior
changes.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yml
Review profile: CHILL
Plan: Pro
Run ID: e5ba2ad3-9271-4bff-aade-3ca1b607d7bb
📒 Files selected for processing (2)
crates/capi/src/lib.rscrates/capi/src/pyframe.rs
22d84b6 to
df6b670
Compare
a6f9e96 to
adf5995
Compare
Summary by CodeRabbit