Skip to content

Commit dd56d1d

Browse files
function
1 parent 010969f commit dd56d1d

File tree

3 files changed

+45
-23
lines changed

3 files changed

+45
-23
lines changed

vm/src/obj/objfunction.rs

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,34 @@
1+
use crate::frame::ScopeRef;
12
use crate::pyobject::{
2-
AttributeProtocol, IdProtocol, PyContext, PyFuncArgs, PyObjectPayload, PyResult, TypeProtocol,
3+
AttributeProtocol, IdProtocol, PyContext, PyFuncArgs, PyObjectPayload2, PyObjectRef, PyResult,
4+
TypeProtocol,
35
};
46
use crate::vm::VirtualMachine;
57

8+
#[derive(Debug)]
9+
pub struct PyFunction {
10+
// TODO: these shouldn't be public
11+
pub code: PyObjectRef,
12+
pub scope: ScopeRef,
13+
pub defaults: PyObjectRef,
14+
}
15+
16+
impl PyFunction {
17+
pub fn new(code: PyObjectRef, scope: ScopeRef, defaults: PyObjectRef) -> Self {
18+
PyFunction {
19+
code,
20+
scope,
21+
defaults,
22+
}
23+
}
24+
}
25+
26+
impl PyObjectPayload2 for PyFunction {
27+
fn required_type(ctx: &PyContext) -> PyObjectRef {
28+
ctx.function_type()
29+
}
30+
}
31+
632
pub fn init(context: &PyContext) {
733
let function_type = &context.function_type;
834
context.set_attr(&function_type, "__get__", context.new_rustfunc(bind_method));
@@ -79,9 +105,9 @@ fn bind_method(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
79105
}
80106

81107
fn function_code(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
82-
match args.args[0].payload {
83-
PyObjectPayload::Function { ref code, .. } => Ok(code.clone()),
84-
_ => Err(vm.new_type_error("no code".to_string())),
108+
match args.args[0].payload() {
109+
Some(PyFunction { ref code, .. }) => Ok(code.clone()),
110+
None => Err(vm.new_type_error("no code".to_string())),
85111
}
86112
}
87113

vm/src/pyobject.rs

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ use crate::obj::objenumerate;
2424
use crate::obj::objfilter;
2525
use crate::obj::objfloat::{self, PyFloat};
2626
use crate::obj::objframe;
27-
use crate::obj::objfunction;
27+
use crate::obj::objfunction::{self, PyFunction};
2828
use crate::obj::objgenerator;
2929
use crate::obj::objint::{self, PyInt};
3030
use crate::obj::objiter;
@@ -657,10 +657,8 @@ impl PyContext {
657657
defaults: PyObjectRef,
658658
) -> PyObjectRef {
659659
PyObject::new(
660-
PyObjectPayload::Function {
661-
code: code_obj,
662-
scope,
663-
defaults,
660+
PyObjectPayload::AnyRustValue {
661+
value: Box::new(PyFunction::new(code_obj, scope, defaults)),
664662
},
665663
self.function_type(),
666664
)
@@ -1510,11 +1508,6 @@ pub enum PyObjectPayload {
15101508
Frame {
15111509
frame: Frame,
15121510
},
1513-
Function {
1514-
code: PyObjectRef,
1515-
scope: ScopeRef,
1516-
defaults: PyObjectRef,
1517-
},
15181511
Generator {
15191512
frame: PyObjectRef,
15201513
},
@@ -1548,7 +1541,6 @@ impl fmt::Debug for PyObjectPayload {
15481541
PyObjectPayload::WeakRef { .. } => write!(f, "weakref"),
15491542
PyObjectPayload::Iterator { .. } => write!(f, "iterator"),
15501543
PyObjectPayload::Slice { .. } => write!(f, "slice"),
1551-
PyObjectPayload::Function { .. } => write!(f, "function"),
15521544
PyObjectPayload::Generator { .. } => write!(f, "generator"),
15531545
PyObjectPayload::BoundMethod {
15541546
ref function,

vm/src/vm.rs

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ use crate::frame::{Scope, ScopeRef};
1818
use crate::obj::objbool;
1919
use crate::obj::objcode;
2020
use crate::obj::objframe;
21+
use crate::obj::objfunction::PyFunction;
2122
use crate::obj::objgenerator;
2223
use crate::obj::objiter;
2324
use crate::obj::objlist::PyList;
@@ -289,13 +290,16 @@ impl VirtualMachine {
289290
{
290291
let args = args.into();
291292
trace!("Invoke: {:?} {:?}", func_ref, args);
293+
if let Some(PyFunction {
294+
ref code,
295+
ref scope,
296+
ref defaults,
297+
}) = func_ref.payload()
298+
{
299+
return self.invoke_python_function(code, scope, defaults, args);
300+
}
292301
match func_ref.payload {
293302
PyObjectPayload::RustFunction { ref function } => function(self, args),
294-
PyObjectPayload::Function {
295-
ref code,
296-
ref scope,
297-
ref defaults,
298-
} => self.invoke_python_function(code, scope, defaults, args),
299303
PyObjectPayload::BoundMethod {
300304
ref function,
301305
ref object,
@@ -331,11 +335,11 @@ impl VirtualMachine {
331335
}
332336

333337
pub fn invoke_with_locals(&mut self, function: PyObjectRef, locals: PyObjectRef) -> PyResult {
334-
if let PyObjectPayload::Function {
338+
if let Some(PyFunction {
335339
code,
336340
scope,
337-
defaults: _defaults,
338-
} = &function.payload
341+
defaults: _,
342+
}) = &function.payload()
339343
{
340344
let scope = Rc::new(Scope {
341345
locals,

0 commit comments

Comments
 (0)