Add label_arg{,_mut} methods

This commit is contained in:
Noah 2020-12-10 18:44:12 -06:00
parent 74a917a72e
commit 86aa00c473

View file

@ -26,7 +26,7 @@ struct CodeInfo {
varname_cache: IndexSet<String>, varname_cache: IndexSet<String>,
cellvar_cache: IndexSet<String>, cellvar_cache: IndexSet<String>,
freevar_cache: IndexSet<String>, freevar_cache: IndexSet<String>,
label_map: Vec<Option<Label>>, label_map: Vec<Label>,
} }
impl CodeInfo { impl CodeInfo {
fn finalize_code(self) -> CodeObject { fn finalize_code(self) -> CodeObject {
@ -73,27 +73,12 @@ impl CodeInfo {
} }
for instruction in &mut *code.instructions { for instruction in &mut *code.instructions {
use Instruction::*;
// this is a little bit hacky, as until now the data stored inside Labels in // this is a little bit hacky, as until now the data stored inside Labels in
// Instructions is just bookkeeping, but I think it's the best way to do this // Instructions is just bookkeeping, but I think it's the best way to do this
// XXX: any new instruction that uses a label has to be added here if let Some(l) = instruction.label_arg_mut() {
match instruction { let real_label = label_map[l.0];
Jump { target: l } debug_assert!(real_label.0 != usize::MAX, "label wasn't set");
| JumpIfTrue { target: l } *l = real_label;
| JumpIfFalse { target: l }
| JumpIfTrueOrPop { target: l }
| JumpIfFalseOrPop { target: l }
| ForIter { target: l }
| SetupFinally { handler: l }
| SetupExcept { handler: l }
| SetupWith { end: l }
| SetupAsyncWith { end: l }
| SetupLoop { end: l }
| Continue { target: l } => {
*l = label_map[l.0].expect("label never set");
}
_ => {}
} }
} }
code code
@ -2446,7 +2431,7 @@ impl Compiler {
fn new_label(&mut self) -> Label { fn new_label(&mut self) -> Label {
let label_map = &mut self.current_codeinfo().label_map; let label_map = &mut self.current_codeinfo().label_map;
let label = Label(label_map.len()); let label = Label(label_map.len());
label_map.push(None); label_map.push(Label(usize::MAX));
label label
} }
@ -2458,9 +2443,9 @@ impl Compiler {
.. ..
} = self.current_codeinfo(); } = self.current_codeinfo();
let actual_label = Label(instructions.len()); let actual_label = Label(instructions.len());
let prev_val = std::mem::replace(&mut label_map[label.0], Some(actual_label)); let prev_val = std::mem::replace(&mut label_map[label.0], actual_label);
debug_assert!( debug_assert!(
prev_val.map_or(true, |x| x == actual_label), prev_val.0 == usize::MAX || prev_val == actual_label,
"double-set a label" "double-set a label"
); );
} }