(&mut self, vm: &VirtualMachine, before: u8, after: u8)
| 6819 | } |
| 6820 | |
| 6821 | fn execute_unpack_ex(&mut self, vm: &VirtualMachine, before: u8, after: u8) -> FrameResult { |
| 6822 | let (before, after) = (before as usize, after as usize); |
| 6823 | let value = self.pop_value(); |
| 6824 | let not_iterable = value.class().slots.iter.load().is_none() |
| 6825 | && value |
| 6826 | .get_class_attr(vm.ctx.intern_str("__getitem__")) |
| 6827 | .is_none(); |
| 6828 | let elements: Vec<_> = value.try_to_value(vm).map_err(|e| { |
| 6829 | if not_iterable && e.class().is(vm.ctx.exceptions.type_error) { |
| 6830 | vm.new_type_error(format!( |
| 6831 | "cannot unpack non-iterable {} object", |
| 6832 | value.class().name() |
| 6833 | )) |
| 6834 | } else { |
| 6835 | e |
| 6836 | } |
| 6837 | })?; |
| 6838 | let min_expected = before + after; |
| 6839 | |
| 6840 | let middle = elements.len().checked_sub(min_expected).ok_or_else(|| { |
| 6841 | vm.new_value_error(format!( |
| 6842 | "not enough values to unpack (expected at least {}, got {})", |
| 6843 | min_expected, |
| 6844 | elements.len() |
| 6845 | )) |
| 6846 | })?; |
| 6847 | |
| 6848 | let mut elements = elements; |
| 6849 | // Elements on stack from right-to-left: |
| 6850 | self.localsplus.stack_extend( |
| 6851 | elements |
| 6852 | .drain(before + middle..) |
| 6853 | .rev() |
| 6854 | .map(|e| Some(PyStackRef::new_owned(e))), |
| 6855 | ); |
| 6856 | |
| 6857 | let middle_elements = elements.drain(before..).collect(); |
| 6858 | let t = vm.ctx.new_list(middle_elements); |
| 6859 | self.push_value(t.into()); |
| 6860 | |
| 6861 | // Lastly the first reversed values: |
| 6862 | self.localsplus.stack_extend( |
| 6863 | elements |
| 6864 | .into_iter() |
| 6865 | .rev() |
| 6866 | .map(|e| Some(PyStackRef::new_owned(e))), |
| 6867 | ); |
| 6868 | |
| 6869 | Ok(None) |
| 6870 | } |
| 6871 | |
| 6872 | #[inline] |
| 6873 | fn jump(&mut self, label: bytecode::Label) { |
no test coverage detected