mirror of
https://github.com/RustPython/RustPython.git
synced 2026-06-02 19:39:49 +09:00
Add code and frame python objects.
This commit is contained in:
@@ -54,7 +54,7 @@ pub fn compile(
|
||||
trace!("Compilation completed: {:?}", code);
|
||||
Ok(PyObject::new(
|
||||
PyObjectKind::Code { code: code },
|
||||
vm.get_type(),
|
||||
vm.ctx.code_type(),
|
||||
))
|
||||
}
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@ use super::builtins;
|
||||
use super::bytecode;
|
||||
use super::import::import;
|
||||
use super::obj::objbool;
|
||||
use super::obj::objcode;
|
||||
use super::obj::objdict;
|
||||
use super::obj::objiter;
|
||||
use super::obj::objlist;
|
||||
@@ -46,15 +47,6 @@ pub struct Frame {
|
||||
pub lasti: usize, // index of last instruction ran
|
||||
}
|
||||
|
||||
pub fn copy_code(code_obj: PyObjectRef) -> bytecode::CodeObject {
|
||||
let code_obj = code_obj.borrow();
|
||||
if let PyObjectKind::Code { ref code } = code_obj.kind {
|
||||
code.clone()
|
||||
} else {
|
||||
panic!("Must be code obj");
|
||||
}
|
||||
}
|
||||
|
||||
// Running a frame can result in one of the below:
|
||||
pub enum ExecutionResult {
|
||||
Return(PyObjectRef),
|
||||
@@ -78,7 +70,7 @@ impl Frame {
|
||||
// locals.extend(callargs);
|
||||
|
||||
Frame {
|
||||
code: copy_code(code),
|
||||
code: objcode::copy_code(&code),
|
||||
stack: vec![],
|
||||
blocks: vec![],
|
||||
// save the callargs as locals
|
||||
@@ -302,8 +294,13 @@ impl Frame {
|
||||
bytecode::Instruction::ListAppend { i } => {
|
||||
let list_obj = self.nth_value(*i);
|
||||
let item = self.pop_value();
|
||||
// TODO: objlist::list_append()
|
||||
vm.call_method(&list_obj, "append", vec![item])?;
|
||||
objlist::list_append(
|
||||
vm,
|
||||
PyFuncArgs {
|
||||
args: vec![list_obj.clone(), item],
|
||||
kwargs: vec![],
|
||||
},
|
||||
)?;
|
||||
Ok(None)
|
||||
}
|
||||
bytecode::Instruction::SetAdd { i } => {
|
||||
|
||||
@@ -3,9 +3,11 @@
|
||||
pub mod objbool;
|
||||
pub mod objbytearray;
|
||||
pub mod objbytes;
|
||||
pub mod objcode;
|
||||
pub mod objcomplex;
|
||||
pub mod objdict;
|
||||
pub mod objfloat;
|
||||
pub mod objframe;
|
||||
pub mod objfunction;
|
||||
pub mod objgenerator;
|
||||
pub mod objint;
|
||||
|
||||
44
vm/src/obj/objcode.rs
Normal file
44
vm/src/obj/objcode.rs
Normal file
@@ -0,0 +1,44 @@
|
||||
/*! Infamous code object. The python class `code`
|
||||
|
||||
*/
|
||||
|
||||
use super::super::bytecode;
|
||||
use super::super::pyobject::{
|
||||
AttributeProtocol, PyContext, PyFuncArgs, PyObjectKind, PyObjectRef, PyResult, TypeProtocol,
|
||||
};
|
||||
use super::super::vm::VirtualMachine;
|
||||
use super::objtype;
|
||||
|
||||
pub fn init(context: &PyContext) {
|
||||
let ref code_type = context.code_type;
|
||||
code_type.set_attr("__repr__", context.new_rustfunc(code_repr));
|
||||
}
|
||||
|
||||
/// Extract rust bytecode object from a python code object.
|
||||
pub fn copy_code(code_obj: &PyObjectRef) -> bytecode::CodeObject {
|
||||
let code_obj = code_obj.borrow();
|
||||
if let PyObjectKind::Code { ref code } = code_obj.kind {
|
||||
code.clone()
|
||||
} else {
|
||||
panic!("Must be code obj");
|
||||
}
|
||||
}
|
||||
|
||||
fn code_repr(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
arg_check!(vm, args, required = [(o, Some(vm.ctx.code_type()))]);
|
||||
|
||||
// Fetch actual code:
|
||||
let code = copy_code(o);
|
||||
|
||||
let file = if let Some(source_path) = code.source_path {
|
||||
format!(", file {}", source_path)
|
||||
} else {
|
||||
String::new()
|
||||
};
|
||||
|
||||
// TODO: fetch proper line info from code object
|
||||
let line = format!(", line 1");
|
||||
|
||||
let repr = format!("<code object at .. {}{}>", file, line);
|
||||
Ok(vm.new_str(repr))
|
||||
}
|
||||
20
vm/src/obj/objframe.rs
Normal file
20
vm/src/obj/objframe.rs
Normal file
@@ -0,0 +1,20 @@
|
||||
/*! The python `frame` type.
|
||||
|
||||
*/
|
||||
|
||||
use super::super::pyobject::{
|
||||
AttributeProtocol, PyContext, PyFuncArgs, PyObjectRef, PyResult, TypeProtocol,
|
||||
};
|
||||
use super::super::vm::VirtualMachine;
|
||||
use super::objtype;
|
||||
|
||||
pub fn init(context: &PyContext) {
|
||||
let ref frame_type = context.frame_type;
|
||||
frame_type.set_attr("__repr__", context.new_rustfunc(frame_repr));
|
||||
}
|
||||
|
||||
fn frame_repr(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
arg_check!(vm, args, required = [(_frame, Some(vm.ctx.frame_type()))]);
|
||||
let repr = format!("<frame object at .. >");
|
||||
Ok(vm.new_str(repr))
|
||||
}
|
||||
@@ -32,6 +32,8 @@ fn super_init(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
} else {
|
||||
// TODO: implement complex logic here....
|
||||
unimplemented!("TODO: get frame and determine instance and class?");
|
||||
// let frame = vm.get_current_frame();
|
||||
//
|
||||
// vm.get_none()
|
||||
};
|
||||
|
||||
|
||||
@@ -4,9 +4,11 @@ use super::frame::Frame;
|
||||
use super::obj::objbool;
|
||||
use super::obj::objbytearray;
|
||||
use super::obj::objbytes;
|
||||
use super::obj::objcode;
|
||||
use super::obj::objcomplex;
|
||||
use super::obj::objdict;
|
||||
use super::obj::objfloat;
|
||||
use super::obj::objframe;
|
||||
use super::obj::objfunction;
|
||||
use super::obj::objgenerator;
|
||||
use super::obj::objint;
|
||||
@@ -70,31 +72,44 @@ impl fmt::Display for PyObjectRef {
|
||||
}
|
||||
}*/
|
||||
|
||||
/*
|
||||
// Idea: implement the iterator trait upon PyObjectRef
|
||||
impl Iterator for (VirtualMachine, PyObjectRef) {
|
||||
type Item = char;
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
// call method ("_next__")
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct PyContext {
|
||||
pub type_type: PyObjectRef,
|
||||
pub none: PyObjectRef,
|
||||
pub classmethod_type: PyObjectRef,
|
||||
pub staticmethod_type: PyObjectRef,
|
||||
pub dict_type: PyObjectRef,
|
||||
pub int_type: PyObjectRef,
|
||||
pub float_type: PyObjectRef,
|
||||
pub complex_type: PyObjectRef,
|
||||
pub bytes_type: PyObjectRef,
|
||||
pub bytearray_type: PyObjectRef,
|
||||
pub bool_type: PyObjectRef,
|
||||
pub classmethod_type: PyObjectRef,
|
||||
pub code_type: PyObjectRef,
|
||||
pub dict_type: PyObjectRef,
|
||||
pub float_type: PyObjectRef,
|
||||
pub frame_type: PyObjectRef,
|
||||
pub frozenset_type: PyObjectRef,
|
||||
pub generator_type: PyObjectRef,
|
||||
pub int_type: PyObjectRef,
|
||||
pub iter_type: PyObjectRef,
|
||||
pub complex_type: PyObjectRef,
|
||||
pub true_value: PyObjectRef,
|
||||
pub false_value: PyObjectRef,
|
||||
pub list_type: PyObjectRef,
|
||||
pub none: PyObjectRef,
|
||||
pub tuple_type: PyObjectRef,
|
||||
pub set_type: PyObjectRef,
|
||||
pub frozenset_type: PyObjectRef,
|
||||
pub iter_type: PyObjectRef,
|
||||
pub staticmethod_type: PyObjectRef,
|
||||
pub super_type: PyObjectRef,
|
||||
pub str_type: PyObjectRef,
|
||||
pub type_type: PyObjectRef,
|
||||
pub function_type: PyObjectRef,
|
||||
pub property_type: PyObjectRef,
|
||||
pub generator_type: PyObjectRef,
|
||||
pub module_type: PyObjectRef,
|
||||
pub bound_method_type: PyObjectRef,
|
||||
pub member_descriptor_type: PyObjectRef,
|
||||
@@ -162,12 +177,14 @@ impl PyContext {
|
||||
let frozenset_type = create_type("frozenset", &type_type, &object_type, &dict_type);
|
||||
let int_type = create_type("int", &type_type, &object_type, &dict_type);
|
||||
let float_type = create_type("float", &type_type, &object_type, &dict_type);
|
||||
let frame_type = create_type("frame", &type_type, &object_type, &dict_type);
|
||||
let complex_type = create_type("complex", &type_type, &object_type, &dict_type);
|
||||
let bytes_type = create_type("bytes", &type_type, &object_type, &dict_type);
|
||||
let bytearray_type = create_type("bytearray", &type_type, &object_type, &dict_type);
|
||||
let tuple_type = create_type("tuple", &type_type, &object_type, &dict_type);
|
||||
let iter_type = create_type("iter", &type_type, &object_type, &dict_type);
|
||||
let bool_type = create_type("bool", &type_type, &int_type, &dict_type);
|
||||
let code_type = create_type("code", &type_type, &int_type, &dict_type);
|
||||
let exceptions = exceptions::ExceptionZoo::new(&type_type, &object_type, &dict_type);
|
||||
|
||||
let none = PyObject::new(
|
||||
@@ -186,17 +203,19 @@ impl PyContext {
|
||||
bool_type.clone(),
|
||||
);
|
||||
let context = PyContext {
|
||||
int_type: int_type,
|
||||
float_type: float_type,
|
||||
bool_type: bool_type,
|
||||
bytearray_type: bytearray_type,
|
||||
bytes_type: bytes_type,
|
||||
code_type: code_type,
|
||||
complex_type: complex_type,
|
||||
classmethod_type: classmethod_type,
|
||||
int_type: int_type,
|
||||
float_type: float_type,
|
||||
frame_type: frame_type,
|
||||
staticmethod_type: staticmethod_type,
|
||||
bytes_type: bytes_type,
|
||||
bytearray_type: bytearray_type,
|
||||
list_type: list_type,
|
||||
set_type: set_type,
|
||||
frozenset_type: frozenset_type,
|
||||
bool_type: bool_type,
|
||||
true_value: true_value,
|
||||
false_value: false_value,
|
||||
tuple_type: tuple_type,
|
||||
@@ -234,28 +253,42 @@ impl PyContext {
|
||||
objtuple::init(&context);
|
||||
objiter::init(&context);
|
||||
objbool::init(&context);
|
||||
objcode::init(&context);
|
||||
objframe::init(&context);
|
||||
exceptions::init(&context);
|
||||
context
|
||||
}
|
||||
|
||||
pub fn int_type(&self) -> PyObjectRef {
|
||||
self.int_type.clone()
|
||||
}
|
||||
|
||||
pub fn float_type(&self) -> PyObjectRef {
|
||||
self.float_type.clone()
|
||||
}
|
||||
|
||||
pub fn complex_type(&self) -> PyObjectRef {
|
||||
self.complex_type.clone()
|
||||
pub fn bytearray_type(&self) -> PyObjectRef {
|
||||
self.bytearray_type.clone()
|
||||
}
|
||||
|
||||
pub fn bytes_type(&self) -> PyObjectRef {
|
||||
self.bytes_type.clone()
|
||||
}
|
||||
|
||||
pub fn bytearray_type(&self) -> PyObjectRef {
|
||||
self.bytearray_type.clone()
|
||||
pub fn code_type(&self) -> PyObjectRef {
|
||||
self.code_type.clone()
|
||||
}
|
||||
|
||||
pub fn complex_type(&self) -> PyObjectRef {
|
||||
self.complex_type.clone()
|
||||
}
|
||||
|
||||
pub fn dict_type(&self) -> PyObjectRef {
|
||||
self.dict_type.clone()
|
||||
}
|
||||
|
||||
pub fn float_type(&self) -> PyObjectRef {
|
||||
self.float_type.clone()
|
||||
}
|
||||
|
||||
pub fn frame_type(&self) -> PyObjectRef {
|
||||
self.frame_type.clone()
|
||||
}
|
||||
|
||||
pub fn int_type(&self) -> PyObjectRef {
|
||||
self.int_type.clone()
|
||||
}
|
||||
|
||||
pub fn list_type(&self) -> PyObjectRef {
|
||||
@@ -282,10 +315,6 @@ impl PyContext {
|
||||
self.iter_type.clone()
|
||||
}
|
||||
|
||||
pub fn dict_type(&self) -> PyObjectRef {
|
||||
self.dict_type.clone()
|
||||
}
|
||||
|
||||
pub fn str_type(&self) -> PyObjectRef {
|
||||
self.str_type.clone()
|
||||
}
|
||||
|
||||
@@ -40,6 +40,8 @@ pub fn mk_module(ctx: &PyContext) -> PyObjectRef {
|
||||
py_mod.set_item("new_class", ctx.new_rustfunc(types_new_class));
|
||||
py_mod.set_item("FunctionType", ctx.function_type());
|
||||
py_mod.set_item("LambdaType", ctx.function_type());
|
||||
py_mod.set_item("CodeType", ctx.code_type());
|
||||
py_mod.set_item("FrameType", ctx.frame_type());
|
||||
|
||||
py_mod
|
||||
}
|
||||
|
||||
@@ -10,7 +10,8 @@ use std::collections::hash_map::HashMap;
|
||||
|
||||
use super::builtins;
|
||||
use super::bytecode;
|
||||
use super::frame::{copy_code, Frame};
|
||||
use super::frame::Frame;
|
||||
use super::obj::objcode::copy_code;
|
||||
use super::obj::objgenerator;
|
||||
use super::obj::objiter;
|
||||
use super::obj::objsequence;
|
||||
@@ -252,7 +253,7 @@ impl VirtualMachine {
|
||||
defaults: &PyObjectRef,
|
||||
args: PyFuncArgs,
|
||||
) -> PyResult {
|
||||
let code_object = copy_code(code.clone());
|
||||
let code_object = copy_code(code);
|
||||
let scope = self.ctx.new_scope(Some(scope.clone()));
|
||||
self.fill_scope_from_args(&code_object, &scope, args, defaults)?;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user