Add traceback object

This commit is contained in:
Aviv Palivoda committed 2019-10-27 19:25:20 +02:00
1 parent a828249fc0
commit a9c2f5f711
8 files changed
+96 -17

No files matched your search

+1 -1
View File
@@ -16,7 +16,7 @@ fn exception_init(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
vm.set_attr(&exc_self, "args", exc_args)?;
// TODO: have an actual `traceback` object for __traceback__
vm.set_attr(&exc_self, "__traceback__", vm.ctx.new_list(vec![]))?;
vm.set_attr(&exc_self, "__traceback__", vm.get_none())?;
vm.set_attr(&exc_self, "__cause__", vm.get_none())?;
vm.set_attr(&exc_self, "__context__", vm.get_none())?;
vm.set_attr(&exc_self, "__suppress_context__", vm.new_bool(false))?;
+14 -13
View File
@@ -14,6 +14,7 @@ use crate::obj::objlist;
use crate::obj::objslice::PySlice;
use crate::obj::objstr;
use crate::obj::objstr::PyString;
use crate::obj::objtraceback::PyTraceback;
use crate::obj::objtuple::PyTuple;
use crate::obj::objtype;
use crate::obj::objtype::PyClassRef;
@@ -80,6 +81,7 @@ enum UnwindReason {
}
#[pyclass]
#[derive(Clone)]
pub struct Frame {
pub code: PyCodeRef,
// We need 1 stack per frame
@@ -167,12 +169,6 @@ impl Frame {
// #[cfg_attr(feature = "flame-it", flame("Frame"))]
pub fn run(&self, vm: &VirtualMachine) -> PyResult<ExecutionResult> {
flame_guard!(format!("Frame::run({})", self.code.obj_name));
let filename = &self.code.source_path.to_string();
// This is the name of the object being run:
let run_obj_name = &self.code.obj_name.to_string();
// Execute until return or exception:
loop {
let lineno = self.get_lineno();
@@ -191,16 +187,21 @@ impl Frame {
&exception,
&vm.ctx.exceptions.base_exception_type
));
let traceback = vm
.get_attribute(exception.clone(), "__traceback__")
.unwrap();
vm_trace!("Adding to traceback: {:?} {:?}", traceback, lineno);
let raise_location = vm.ctx.new_tuple(vec![
vm.ctx.new_str(filename.clone()),
vm.ctx.new_int(lineno.row()),
vm.ctx.new_str(run_obj_name.clone()),
]);
objlist::PyListRef::try_from_object(vm, traceback)?.append(raise_location, vm);
let new_traceback = PyTraceback::new(
traceback,
self.clone().into_ref(vm),
self.lasti.get(),
lineno.row(),
vm,
);
vm.set_attr(&exception, "__traceback__", new_traceback.into_ref(vm))
.unwrap();
vm_trace!("Adding to traceback: {:?} {:?}", new_traceback, lineno);
match self.unwind_blocks(vm, UnwindReason::Raising { exception }) {
Ok(None) => {}
Ok(Some(result)) => {
-1
View File
@@ -66,7 +66,6 @@ pub mod pyobject;
pub mod scope;
pub mod stdlib;
mod sysmodule;
mod traceback;
pub mod types;
pub mod util;
mod version;
+1
View File
@@ -34,6 +34,7 @@ pub mod objslice;
pub mod objstaticmethod;
pub mod objstr;
pub mod objsuper;
pub mod objtraceback;
pub mod objtuple;
pub mod objtype;
pub mod objweakproxy;
+71
View File
@@ -0,0 +1,71 @@
use crate::frame::FrameRef;
use crate::obj::objtype::PyClassRef;
use crate::pyobject::{PyClassImpl, PyContext, PyObjectRef, PyRef, PyValue};
use crate::vm::VirtualMachine;
#[pyclass]
#[derive(Debug)]
pub struct PyTraceback {
next: Option<PyTracebackRef>,
frame: FrameRef,
lasti: usize,
lineno: usize,
}
type PyTracebackRef = PyRef<PyTraceback>;
impl PyValue for PyTraceback {
fn class(vm: &VirtualMachine) -> PyClassRef {
vm.ctx.traceback_type()
}
}
#[pyimpl]
impl PyTraceback {
pub fn new(
next: PyObjectRef,
frame: FrameRef,
lasti: usize,
lineno: usize,
vm: &VirtualMachine,
) -> Self {
let next = if vm.is_none(&next) {
None
} else {
let traceback: PyTracebackRef =
next.downcast().expect("next must be a traceback object");
Some(traceback)
};
PyTraceback {
next,
frame,
lasti,
lineno,
}
}
#[pyproperty(name = "tb_frame")]
fn frame(&self, _vm: &VirtualMachine) -> FrameRef {
self.frame.clone()
}
#[pyproperty(name = "tb_lasti")]
fn lasti(&self, _vm: &VirtualMachine) -> usize {
self.lasti
}
#[pyproperty(name = "tb_lineno")]
fn lineno(&self, _vm: &VirtualMachine) -> usize {
self.lineno
}
#[pyproperty(name = "tb_next")]
fn next_get(&self, _vm: &VirtualMachine) -> Option<PyTracebackRef> {
self.next.as_ref().map(|x| x.clone())
}
}
pub fn init(context: &PyContext) {
PyTraceback::extend_class(context, &context.types.traceback_type);
}
+4
View File
@@ -349,6 +349,10 @@ impl PyContext {
self.types.weakproxy_type.clone()
}
pub fn traceback_type(&self) -> PyClassRef {
self.types.traceback_type.clone()
}
pub fn type_type(&self) -> PyClassRef {
self.types.type_type.clone()
}
-2
View File
@@ -1,2 +0,0 @@
// python tracebacks
//
+5
View File
@@ -29,6 +29,7 @@ use crate::obj::objslice;
use crate::obj::objstaticmethod;
use crate::obj::objstr;
use crate::obj::objsuper;
use crate::obj::objtraceback;
use crate::obj::objtuple;
use crate::obj::objtype::{self, PyClass, PyClassRef};
use crate::obj::objweakproxy;
@@ -93,6 +94,7 @@ pub struct TypeZoo {
pub weakref_type: PyClassRef,
pub weakproxy_type: PyClassRef,
pub mappingproxy_type: PyClassRef,
pub traceback_type: PyClassRef,
pub object_type: PyClassRef,
}
@@ -158,6 +160,7 @@ impl TypeZoo {
let rangeiterator_type = create_type("range_iterator", &type_type, &object_type);
let slice_type = create_type("slice", &type_type, &object_type);
let mappingproxy_type = create_type("mappingproxy", &type_type, &object_type);
let traceback_type = create_type("traceback", &type_type, &object_type);
Self {
bool_type,
@@ -212,6 +215,7 @@ impl TypeZoo {
weakref_type,
weakproxy_type,
type_type,
traceback_type,
}
}
}
@@ -313,4 +317,5 @@ pub fn initialize_types(context: &PyContext) {
objmodule::init(&context);
objnamespace::init(&context);
objmappingproxy::init(&context);
objtraceback::init(&context);
}