Skip to content

Commit 8b3a95c

Browse files
committed
Add code object name to traceback
1 parent 608a8ea commit 8b3a95c

File tree

4 files changed

+38
-10
lines changed

4 files changed

+38
-10
lines changed

vm/src/bytecode.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,16 +23,22 @@ pub struct CodeObject {
2323
pub locations: Vec<ast::Location>,
2424
pub arg_names: Vec<String>,
2525
pub source_path: Option<String>,
26+
pub obj_name: String, // Name of the object that created this code object
2627
}
2728

2829
impl CodeObject {
29-
pub fn new(arg_names: Vec<String>, source_path: Option<String>) -> CodeObject {
30+
pub fn new(
31+
arg_names: Vec<String>,
32+
source_path: Option<String>,
33+
obj_name: String,
34+
) -> CodeObject {
3035
CodeObject {
3136
instructions: Vec::new(),
3237
label_map: HashMap::new(),
3338
locations: Vec::new(),
3439
arg_names: arg_names,
3540
source_path: source_path,
41+
obj_name: obj_name,
3642
}
3743
}
3844
}

vm/src/compile.rs

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ use super::vm::VirtualMachine;
1212
struct Compiler {
1313
code_object_stack: Vec<CodeObject>,
1414
nxt_label: usize,
15+
source_path: Option<String>,
1516
current_source_location: ast::Location,
1617
}
1718

@@ -22,7 +23,8 @@ pub fn compile(
2223
source_path: Option<String>,
2324
) -> Result<PyObjectRef, String> {
2425
let mut compiler = Compiler::new();
25-
compiler.push_new_code_object(source_path);
26+
compiler.source_path = source_path.clone();
27+
compiler.push_new_code_object(source_path, "<module>".to_string());
2628
match mode {
2729
Mode::Exec => match parser::parse_program(source) {
2830
Ok(ast) => {
@@ -87,13 +89,14 @@ impl Compiler {
8789
Compiler {
8890
code_object_stack: Vec::new(),
8991
nxt_label: 0,
92+
source_path: None,
9093
current_source_location: ast::Location::default(),
9194
}
9295
}
9396

94-
fn push_new_code_object(&mut self, source_path: Option<String>) {
97+
fn push_new_code_object(&mut self, source_path: Option<String>, obj_name: String) {
9598
self.code_object_stack
96-
.push(CodeObject::new(Vec::new(), source_path.clone()));
99+
.push(CodeObject::new(Vec::new(), source_path.clone(), obj_name));
97100
}
98101

99102
fn pop_code_object(&mut self) -> CodeObject {
@@ -373,7 +376,11 @@ impl Compiler {
373376
});
374377
}
375378

376-
self.code_object_stack.push(CodeObject::new(names, None));
379+
self.code_object_stack.push(CodeObject::new(
380+
names,
381+
self.source_path.clone(),
382+
name.clone(),
383+
));
377384
self.compile_statements(body);
378385

379386
// Emit None at end:
@@ -404,8 +411,11 @@ impl Compiler {
404411
}
405412
ast::Statement::ClassDef { name, body, args } => {
406413
self.emit(Instruction::LoadBuildClass);
407-
self.code_object_stack
408-
.push(CodeObject::new(vec![String::from("__locals__")], None));
414+
self.code_object_stack.push(CodeObject::new(
415+
vec![String::from("__locals__")],
416+
self.source_path.clone(),
417+
name.clone(),
418+
));
409419
self.emit(Instruction::LoadName {
410420
name: String::from("__locals__"),
411421
});
@@ -769,7 +779,8 @@ impl Compiler {
769779
ast::Expression::Lambda { args, body } => {
770780
self.code_object_stack.push(CodeObject::new(
771781
args.iter().map(|(name, _default)| name.clone()).collect(),
772-
None,
782+
self.source_path.clone(),
783+
"<lambda>".to_string(),
773784
));
774785
self.compile_expression(body);
775786
self.emit(Instruction::ReturnValue);

vm/src/exceptions.rs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,8 @@ pub fn print_exception(vm: &mut VirtualMachine, exc: &PyObjectRef) {
2525
if let Some(tb) = exc.get_attr("__traceback__") {
2626
println!("Traceback (most recent call last):");
2727
if objtype::isinstance(tb.clone(), vm.ctx.list_type()) {
28-
let elements = objlist::get_elements(&tb);
28+
let mut elements = objlist::get_elements(&tb);
29+
elements.reverse();
2930
for element in elements {
3031
if objtype::isinstance(element.clone(), vm.ctx.tuple_type()) {
3132
let element = objtuple::get_elements(&element);
@@ -41,7 +42,13 @@ pub fn print_exception(vm: &mut VirtualMachine, exc: &PyObjectRef) {
4142
"<error>".to_string()
4243
};
4344

44-
println!(" File {}, line {}, in ..", filename, lineno);
45+
let obj_name = if let Ok(x) = vm.to_str(element[2].clone()) {
46+
objstr::get_value(&x)
47+
} else {
48+
"<error>".to_string()
49+
};
50+
51+
println!(" File {}, line {}, in {}", filename, lineno, obj_name);
4552
} else {
4653
println!(" File ??");
4754
}

vm/src/vm.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,9 @@ impl VirtualMachine {
243243
"<unknown>".to_string()
244244
};
245245

246+
// This is the name of the object being run:
247+
let run_obj_name = &self.current_frame().code.obj_name.to_string();
248+
246249
// Execute until return or exception:
247250
let value = loop {
248251
let lineno = self.get_lineno();
@@ -266,6 +269,7 @@ impl VirtualMachine {
266269
let pos = self.ctx.new_tuple(vec![
267270
self.ctx.new_str(filename.clone()),
268271
self.ctx.new_int(lineno.get_row() as i32),
272+
self.ctx.new_str(run_obj_name.clone()),
269273
]);
270274
objlist::append(
271275
self,

0 commit comments

Comments
 (0)