Skip to content

Commit 2cc83ed

Browse files
committed
clean up Frame
1 parent b052d64 commit 2cc83ed

File tree

3 files changed

+71
-69
lines changed

3 files changed

+71
-69
lines changed

stdlib/src/faulthandler.rs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,9 @@ pub(crate) use decl::make_module;
22

33
#[pymodule(name = "faulthandler")]
44
mod decl {
5-
use crate::vm::{
6-
frame::FrameRef, function::OptionalArg, stdlib::sys::PyStderr, VirtualMachine,
7-
};
5+
use crate::vm::{frame::Frame, function::OptionalArg, stdlib::sys::PyStderr, VirtualMachine};
86

9-
fn dump_frame(frame: &FrameRef, vm: &VirtualMachine) {
7+
fn dump_frame(frame: &Frame, vm: &VirtualMachine) {
108
let stderr = PyStderr(vm);
119
writeln!(
1210
stderr,

vm/src/builtins/frame.rs

Lines changed: 28 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,6 @@ pub fn init(context: &Context) {
1616
Frame::extend_class(context, context.types.frame_type);
1717
}
1818

19-
#[pyclass(with(Constructor, PyRef, Representable))]
20-
impl Frame {}
21-
2219
impl Unconstructible for Frame {}
2320

2421
impl Representable for Frame {
@@ -34,61 +31,46 @@ impl Representable for Frame {
3431
}
3532
}
3633

37-
#[pyclass]
38-
impl PyRef<Frame> {
34+
#[pyclass(with(Constructor, Py))]
35+
impl Frame {
3936
#[pymethod]
40-
fn clear(self) {
37+
fn clear(&self) {
4138
// TODO
4239
}
4340

4441
#[pygetset]
45-
fn f_globals(self) -> PyDictRef {
42+
fn f_globals(&self) -> PyDictRef {
4643
self.globals.clone()
4744
}
4845

4946
#[pygetset]
50-
fn f_locals(self, vm: &VirtualMachine) -> PyResult {
47+
fn f_locals(&self, vm: &VirtualMachine) -> PyResult {
5148
self.locals(vm).map(Into::into)
5249
}
5350

5451
#[pygetset]
55-
pub fn f_code(self) -> PyRef<PyCode> {
52+
pub fn f_code(&self) -> PyRef<PyCode> {
5653
self.code.clone()
5754
}
5855

5956
#[pygetset]
60-
pub fn f_back(self, vm: &VirtualMachine) -> Option<Self> {
61-
// TODO: actually store f_back inside Frame struct
62-
63-
// get the frame in the frame stack that appears before this one.
64-
// won't work if this frame isn't in the frame stack, hence the todo above
65-
vm.frames
66-
.borrow()
67-
.iter()
68-
.rev()
69-
.skip_while(|p| !p.is(&self))
70-
.nth(1)
71-
.cloned()
72-
}
73-
74-
#[pygetset]
75-
fn f_lasti(self) -> u32 {
57+
fn f_lasti(&self) -> u32 {
7658
self.lasti()
7759
}
7860

7961
#[pygetset]
80-
pub fn f_lineno(self) -> usize {
62+
pub fn f_lineno(&self) -> usize {
8163
self.current_location().row()
8264
}
8365

8466
#[pygetset]
85-
fn f_trace(self) -> PyObjectRef {
67+
fn f_trace(&self) -> PyObjectRef {
8668
let boxed = self.trace.lock();
8769
boxed.clone()
8870
}
8971

9072
#[pygetset(setter)]
91-
fn set_f_trace(self, value: PySetterValue, vm: &VirtualMachine) {
73+
fn set_f_trace(&self, value: PySetterValue, vm: &VirtualMachine) {
9274
let mut storage = self.trace.lock();
9375
*storage = value.unwrap_or_none(vm);
9476
}
@@ -126,3 +108,21 @@ impl PyRef<Frame> {
126108
}
127109
}
128110
}
111+
112+
#[pyclass]
113+
impl Py<Frame> {
114+
#[pygetset]
115+
pub fn f_back(&self, vm: &VirtualMachine) -> Option<PyRef<Frame>> {
116+
// TODO: actually store f_back inside Frame struct
117+
118+
// get the frame in the frame stack that appears before this one.
119+
// won't work if this frame isn't in the frame stack, hence the todo above
120+
vm.frames
121+
.borrow()
122+
.iter()
123+
.rev()
124+
.skip_while(|p| !p.is(self.as_object()))
125+
.nth(1)
126+
.cloned()
127+
}
128+
}

vm/src/frame.rs

Lines changed: 41 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -164,24 +164,20 @@ impl Frame {
164164
temporary_refs: PyMutex::new(vec![]),
165165
}
166166
}
167-
}
168167

169-
impl FrameRef {
170-
#[inline(always)]
171-
fn with_exec<R>(&self, f: impl FnOnce(ExecutingFrame) -> R) -> R {
172-
let mut state = self.state.lock();
173-
let exec = ExecutingFrame {
174-
code: &self.code,
175-
fastlocals: &self.fastlocals,
176-
cells_frees: &self.cells_frees,
177-
locals: &self.locals,
178-
globals: &self.globals,
179-
builtins: &self.builtins,
180-
lasti: &self.lasti,
181-
object: self,
182-
state: &mut state,
183-
};
184-
f(exec)
168+
pub fn current_location(&self) -> bytecode::Location {
169+
self.code.locations[self.lasti() as usize - 1]
170+
}
171+
172+
pub fn lasti(&self) -> u32 {
173+
#[cfg(feature = "threading")]
174+
{
175+
self.lasti.load(atomic::Ordering::Relaxed)
176+
}
177+
#[cfg(not(feature = "threading"))]
178+
{
179+
self.lasti.get()
180+
}
185181
}
186182

187183
pub fn locals(&self, vm: &VirtualMachine) -> PyResult<ArgMapping> {
@@ -221,6 +217,25 @@ impl FrameRef {
221217
}
222218
Ok(locals.clone())
223219
}
220+
}
221+
222+
impl Py<Frame> {
223+
#[inline(always)]
224+
fn with_exec<R>(&self, f: impl FnOnce(ExecutingFrame) -> R) -> R {
225+
let mut state = self.state.lock();
226+
let exec = ExecutingFrame {
227+
code: &self.code,
228+
fastlocals: &self.fastlocals,
229+
cells_frees: &self.cells_frees,
230+
locals: &self.locals,
231+
globals: &self.globals,
232+
builtins: &self.builtins,
233+
lasti: &self.lasti,
234+
object: self,
235+
state: &mut state,
236+
};
237+
f(exec)
238+
}
224239

225240
// #[cfg_attr(feature = "flame-it", flame("Frame"))]
226241
pub fn run(&self, vm: &VirtualMachine) -> PyResult<ExecutionResult> {
@@ -250,34 +265,19 @@ impl FrameRef {
250265
self.with_exec(|mut exec| exec.gen_throw(vm, exc_type, exc_val, exc_tb))
251266
}
252267

253-
pub fn current_location(&self) -> bytecode::Location {
254-
self.code.locations[self.lasti() as usize - 1]
255-
}
256-
257268
pub fn yield_from_target(&self) -> Option<PyObjectRef> {
258269
self.with_exec(|exec| exec.yield_from_target().map(PyObject::to_owned))
259270
}
260271

261-
pub fn lasti(&self) -> u32 {
262-
#[cfg(feature = "threading")]
263-
{
264-
self.lasti.load(atomic::Ordering::Relaxed)
265-
}
266-
#[cfg(not(feature = "threading"))]
267-
{
268-
self.lasti.get()
269-
}
270-
}
271-
272272
pub fn is_internal_frame(&self) -> bool {
273-
let code = self.clone().f_code();
273+
let code = self.f_code();
274274
let filename = code.co_filename();
275275

276276
filename.as_str().contains("importlib") && filename.as_str().contains("_bootstrap")
277277
}
278278

279279
pub fn next_external_frame(&self, vm: &VirtualMachine) -> Option<FrameRef> {
280-
self.clone().f_back(vm).map(|mut back| loop {
280+
self.f_back(vm).map(|mut back| loop {
281281
back = if let Some(back) = back.to_owned().f_back(vm) {
282282
back
283283
} else {
@@ -300,7 +300,7 @@ struct ExecutingFrame<'a> {
300300
locals: &'a ArgMapping,
301301
globals: &'a PyDictRef,
302302
builtins: &'a PyDictRef,
303-
object: &'a FrameRef,
303+
object: &'a Py<Frame>,
304304
lasti: &'a Lasti,
305305
state: &'a mut FrameState,
306306
}
@@ -376,8 +376,12 @@ impl ExecutingFrame<'_> {
376376

377377
let loc = frame.code.locations[idx];
378378
let next = exception.traceback();
379-
let new_traceback =
380-
PyTraceback::new(next, frame.object.clone(), frame.lasti(), loc.row());
379+
let new_traceback = PyTraceback::new(
380+
next,
381+
frame.object.to_owned(),
382+
frame.lasti(),
383+
loc.row(),
384+
);
381385
vm_trace!("Adding to traceback: {:?} {:?}", new_traceback, loc.row());
382386
exception.set_traceback(Some(new_traceback.into_ref(vm)));
383387

0 commit comments

Comments
 (0)