Skip to content

Commit c5b6b61

Browse files
committed
Construct PyObjectRef earlier to avoid the need for Clone on Frame.
1 parent ee86229 commit c5b6b61

File tree

6 files changed

+42
-31
lines changed

6 files changed

+42
-31
lines changed

vm/src/frame.rs

-1
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@ enum Block {
3838
},
3939
}
4040

41-
#[derive(Clone)]
4241
pub struct Frame {
4342
pub code: bytecode::CodeObject,
4443
// We need 1 stack per frame

vm/src/obj/objframe.rs

+13-15
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
33
*/
44

5-
use super::super::frame::Frame;
65
use super::super::pyobject::{
76
AttributeProtocol, PyContext, PyFuncArgs, PyObjectKind, PyObjectRef, PyResult, TypeProtocol,
87
};
@@ -30,26 +29,25 @@ fn frame_repr(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
3029

3130
fn frame_flocals(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
3231
arg_check!(vm, args, required = [(frame, Some(vm.ctx.frame_type()))]);
33-
let frame = get_value(frame);
34-
let py_scope = frame.locals.clone();
35-
let py_scope = py_scope.borrow();
36-
37-
if let PyObjectKind::Scope { scope } = &py_scope.kind {
38-
Ok(scope.locals.clone())
32+
if let PyObjectKind::Frame { ref frame } = frame.borrow().kind {
33+
let py_scope = frame.locals.clone();
34+
let py_scope = py_scope.borrow();
35+
36+
if let PyObjectKind::Scope { scope } = &py_scope.kind {
37+
Ok(scope.locals.clone())
38+
} else {
39+
panic!("The scope isn't a scope!");
40+
}
3941
} else {
40-
panic!("The scope isn't a scope!");
42+
panic!("Frame doesn't contain a frame: {:?}", frame);
4143
}
4244
}
4345

4446
fn frame_fcode(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
4547
arg_check!(vm, args, required = [(frame, Some(vm.ctx.frame_type()))]);
46-
Ok(vm.ctx.new_code_object(get_value(frame).code))
47-
}
48-
49-
pub fn get_value(obj: &PyObjectRef) -> Frame {
50-
if let PyObjectKind::Frame { frame } = &obj.borrow().kind {
51-
frame.clone()
48+
if let PyObjectKind::Frame { ref frame } = frame.borrow().kind {
49+
Ok(vm.ctx.new_code_object(frame.code.clone()))
5250
} else {
53-
panic!("Inner error getting int {:?}", obj);
51+
panic!("Frame doesn't contain a frame: {:?}", frame);
5452
}
5553
}

vm/src/obj/objgenerator.rs

+8-3
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
* The mythical generator.
33
*/
44

5-
use super::super::frame::{ExecutionResult, Frame};
5+
use super::super::frame::ExecutionResult;
66
use super::super::pyobject::{
77
AttributeProtocol, PyContext, PyFuncArgs, PyObject, PyObjectKind, PyObjectRef, PyResult,
88
TypeProtocol,
@@ -17,7 +17,7 @@ pub fn init(context: &PyContext) {
1717
generator_type.set_attr("send", context.new_rustfunc(generator_send));
1818
}
1919

20-
pub fn new_generator(vm: &mut VirtualMachine, frame: Frame) -> PyResult {
20+
pub fn new_generator(vm: &mut VirtualMachine, frame: PyObjectRef) -> PyResult {
2121
let g = PyObject::new(
2222
PyObjectKind::Generator { frame: frame },
2323
vm.ctx.generator_type.clone(),
@@ -47,7 +47,12 @@ fn generator_send(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
4747

4848
fn send(vm: &mut VirtualMachine, gen: &PyObjectRef, value: &PyObjectRef) -> PyResult {
4949
if let PyObjectKind::Generator { ref mut frame } = gen.borrow_mut().kind {
50-
frame.push_value(value.clone());
50+
if let PyObjectKind::Frame { ref mut frame } = frame.borrow_mut().kind {
51+
frame.push_value(value.clone());
52+
} else {
53+
panic!("Generator frame isn't a frame.");
54+
}
55+
5156
match vm.run_frame(frame.clone())? {
5257
ExecutionResult::Yield(value) => Ok(value),
5358
ExecutionResult::Return(_value) => {

vm/src/pyobject.rs

+8-3
Original file line numberDiff line numberDiff line change
@@ -459,8 +459,13 @@ impl PyContext {
459459
)
460460
}
461461

462-
pub fn new_frame(&self, frame: Frame) -> PyObjectRef {
463-
PyObject::new(PyObjectKind::Frame { frame: frame }, self.frame_type())
462+
pub fn new_frame(&self, code: PyObjectRef, scope: PyObjectRef) -> PyObjectRef {
463+
PyObject::new(
464+
PyObjectKind::Frame {
465+
frame: Frame::new(code, scope),
466+
},
467+
self.frame_type(),
468+
)
464469
}
465470

466471
pub fn new_property(&self, function: RustPyFunc) -> PyObjectRef {
@@ -811,7 +816,7 @@ pub enum PyObjectKind {
811816
defaults: PyObjectRef,
812817
},
813818
Generator {
814-
frame: Frame,
819+
frame: PyObjectRef,
815820
},
816821
BoundMethod {
817822
function: PyObjectRef,

vm/src/sysmodule.rs

+1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use super::vm::VirtualMachine;
55
use num_bigint::ToBigInt;
66
use num_traits::ToPrimitive;
77
use std::env;
8+
use std::mem;
89
use std::rc::Rc;
910

1011
/*

vm/src/vm.rs

+12-9
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,8 @@ use std::collections::hash_map::HashMap;
1010

1111
use super::builtins;
1212
use super::bytecode;
13-
use super::frame::{ExecutionResult, Frame};
13+
use super::frame::ExecutionResult;
1414
use super::obj::objcode::copy_code;
15-
use super::obj::objframe;
1615
use super::obj::objgenerator;
1716
use super::obj::objiter;
1817
use super::obj::objsequence;
@@ -58,21 +57,25 @@ impl VirtualMachine {
5857
}
5958

6059
pub fn run_code_obj(&mut self, code: PyObjectRef, scope: PyObjectRef) -> PyResult {
61-
self.run_frame_full(Frame::new(code, scope))
60+
let frame = self.ctx.new_frame(code, scope);
61+
self.run_frame_full(frame)
6262
}
6363

64-
pub fn run_frame_full(&mut self, frame: Frame) -> PyResult {
64+
pub fn run_frame_full(&mut self, frame: PyObjectRef) -> PyResult {
6565
match self.run_frame(frame)? {
6666
ExecutionResult::Return(value) => Ok(value),
6767
_ => panic!("Got unexpected result from function"),
6868
}
6969
}
7070

71-
pub fn run_frame(&mut self, frame: Frame) -> Result<ExecutionResult, PyObjectRef> {
72-
let frame = self.ctx.new_frame(frame);
71+
pub fn run_frame(&mut self, frame: PyObjectRef) -> Result<ExecutionResult, PyObjectRef> {
72+
let result;
7373
self.frames.push(frame.clone());
74-
let mut frame = objframe::get_value(&frame);
75-
let result = frame.run(self);
74+
if let PyObjectKind::Frame { ref mut frame } = frame.borrow_mut().kind {
75+
result = frame.run(self);
76+
} else {
77+
panic!("Frame doesn't contain a frame: {:?}", frame);
78+
}
7679
self.frames.pop();
7780
result
7881
}
@@ -276,7 +279,7 @@ impl VirtualMachine {
276279
self.fill_scope_from_args(&code_object, &scope, args, defaults)?;
277280

278281
// Construct frame:
279-
let frame = Frame::new(code.clone(), scope);
282+
let frame = self.ctx.new_frame(code.clone(), scope);
280283

281284
// If we have a generator, create a new generator
282285
if code_object.is_generator {

0 commit comments

Comments
 (0)