Don't create extra JumpIfOrPop instructions.

As discussed:

https://github.com/RustPython/RustPython/pull/82#discussion_r212809238
This commit is contained in:
Adam Kelly committed 2018-08-26 09:36:27 +01:00
1 parent e10dfa4f87
commit de0dde21f0
3 files changed
+24 -40

No files matched your search

-6
View File
@@ -83,15 +83,9 @@ pub enum Instruction {
JumpIf {
target: Label,
},
JumpIfOrPop {
target: Label,
},
JumpIfFalse {
target: Label,
},
JumpIfFalseOrPop {
target: Label,
},
MakeFunction,
CallFunction {
count: usize,
+6 -2
View File
@@ -545,16 +545,20 @@ impl Compiler {
ast::BooleanOperator::And => {
let false_label = self.new_label();
self.compile_expression(a);
self.emit(Instruction::JumpIfFalseOrPop {
self.emit(Instruction::Duplicate);
self.emit(Instruction::JumpIfFalse {
target: false_label,
});
self.emit(Instruction::Pop);
self.compile_expression(b);
self.set_label(false_label);
}
ast::BooleanOperator::Or => {
let true_label = self.new_label();
self.compile_expression(a);
self.emit(Instruction::JumpIfOrPop { target: true_label });
self.emit(Instruction::Duplicate);
self.emit(Instruction::JumpIf { target: true_label });
self.emit(Instruction::Pop);
self.compile_expression(b);
self.set_label(true_label);
}
+18 -32
View File
@@ -773,22 +773,28 @@ impl VirtualMachine {
}
bytecode::Instruction::JumpIf { target } => {
let obj = self.pop_value();
self.jump_if(target, obj, true, false)
match objbool::boolval(self, obj) {
Ok(value) => {
if value {
self.jump(target);
}
None
}
Err(value) => Some(Err(value)),
}
}
bytecode::Instruction::JumpIfFalse { target } => {
let obj = self.pop_value();
self.jump_if(target, obj, false, false)
}
bytecode::Instruction::JumpIfOrPop { target } => {
let obj = self.last_value();
self.jump_if(target, obj, true, true)
}
bytecode::Instruction::JumpIfFalseOrPop { target } => {
let obj = self.last_value();
self.jump_if(target, obj, false, true)
match objbool::boolval(self, obj) {
Ok(value) => {
if !value {
self.jump(target);
}
None
}
Err(value) => Some(Err(value)),
}
}
bytecode::Instruction::Raise { argc } => {
@@ -873,26 +879,6 @@ impl VirtualMachine {
}
}
fn jump_if(
&mut self,
label: &bytecode::Label,
obj: PyObjectRef,
jump_on: bool,
or_pop: bool,
) -> Option<PyResult> {
match objbool::boolval(self, obj) {
Ok(value) => {
if value == jump_on {
self.jump(label);
} else if or_pop {
self.pop_value();
}
None
}
Err(value) => Some(Err(value)),
}
}
fn jump(&mut self, label: &bytecode::Label) {
let current_frame = self.current_frame();
let target_pc = current_frame.code.label_map[label];