(
&mut self,
vm: &VirtualMachine,
op: bytecode::BinaryOperator,
instr_idx: usize,
cache_base: usize,
)
| 7838 | } |
| 7839 | |
| 7840 | fn specialize_binary_op( |
| 7841 | &mut self, |
| 7842 | vm: &VirtualMachine, |
| 7843 | op: bytecode::BinaryOperator, |
| 7844 | instr_idx: usize, |
| 7845 | cache_base: usize, |
| 7846 | ) { |
| 7847 | if !matches!( |
| 7848 | self.code.instructions.read_op(instr_idx), |
| 7849 | Instruction::BinaryOp { .. } |
| 7850 | ) { |
| 7851 | return; |
| 7852 | } |
| 7853 | let b = self.top_value(); |
| 7854 | let a = self.nth_value(1); |
| 7855 | // `external_cache` in _PyBinaryOpCache is used only by BINARY_OP_EXTEND. |
| 7856 | unsafe { |
| 7857 | self.write_cached_binary_op_extend_descr(cache_base, None); |
| 7858 | } |
| 7859 | let mut cached_extend_descr = None; |
| 7860 | |
| 7861 | let new_op = match op { |
| 7862 | bytecode::BinaryOperator::Add => { |
| 7863 | if a.downcast_ref_if_exact::<PyInt>(vm).is_some() |
| 7864 | && b.downcast_ref_if_exact::<PyInt>(vm).is_some() |
| 7865 | { |
| 7866 | Some(Instruction::BinaryOpAddInt) |
| 7867 | } else if a.downcast_ref_if_exact::<PyFloat>(vm).is_some() |
| 7868 | && b.downcast_ref_if_exact::<PyFloat>(vm).is_some() |
| 7869 | { |
| 7870 | Some(Instruction::BinaryOpAddFloat) |
| 7871 | } else if a.downcast_ref_if_exact::<PyStr>(vm).is_some() |
| 7872 | && b.downcast_ref_if_exact::<PyStr>(vm).is_some() |
| 7873 | { |
| 7874 | if self |
| 7875 | .binary_op_inplace_unicode_target_local(cache_base, a) |
| 7876 | .is_some() |
| 7877 | { |
| 7878 | Some(Instruction::BinaryOpInplaceAddUnicode) |
| 7879 | } else { |
| 7880 | Some(Instruction::BinaryOpAddUnicode) |
| 7881 | } |
| 7882 | } else if let Some(descr) = self.binary_op_extended_specialization(op, a, b, vm) { |
| 7883 | cached_extend_descr = Some(descr); |
| 7884 | Some(Instruction::BinaryOpExtend) |
| 7885 | } else { |
| 7886 | None |
| 7887 | } |
| 7888 | } |
| 7889 | bytecode::BinaryOperator::Subtract => { |
| 7890 | if a.downcast_ref_if_exact::<PyInt>(vm).is_some() |
| 7891 | && b.downcast_ref_if_exact::<PyInt>(vm).is_some() |
| 7892 | { |
| 7893 | Some(Instruction::BinaryOpSubtractInt) |
| 7894 | } else if a.downcast_ref_if_exact::<PyFloat>(vm).is_some() |
| 7895 | && b.downcast_ref_if_exact::<PyFloat>(vm).is_some() |
| 7896 | { |
| 7897 | Some(Instruction::BinaryOpSubtractFloat) |
no test coverage detected