MCPcopy Create free account
hub / github.com/dylan-sutton-chavez/edge-python / exec_for_iter

Method exec_for_iter

compiler/src/modules/vm/dispatch.rs:799–866  ·  view source on GitHub ↗
(&mut self, op: u16, ip: &mut usize, n: usize, chunk: &SSAChunk, slots: &mut [Val])

Source from the content-addressed store, hash-verified

797
798 #[inline(never)]
799 fn exec_for_iter(&mut self, op: u16, ip: &mut usize, n: usize, chunk: &SSAChunk, slots: &mut [Val]) -> Result<(), VmErr> {
800 if !self.sandbox_off {
801 if self.budget == 0 { return Err(cold_budget()); }
802 self.budget -= 1;
803 }
804 if self.heap.needs_gc() { self.collect(slots); }
805 // Coroutine iteration: resume via call instead of next_item().
806 if let Some(IterFrame::Coroutine(coro_val)) = self.iter_stack.last() {
807 let cv = *coro_val;
808 // Resume directly so `yielded` distinguishes a yielded value (even None) from exhaustion.
809 let result = self.resume_coroutine(cv)?;
810 if self.yielded {
811 self.yielded = false;
812 self.push(result);
813 } else {
814 // `yield from gen` evaluates to the subgenerator's return value.
815 self.yield_from_value = result;
816 self.iter_stack.pop();
817 *ip = op as usize;
818 }
819 return Ok(());
820 }
821 // user-defined iterator calls `__next__`; `StopIteration` ends the loop without propagating, other exceptions surface.
822 if let Some(IterFrame::UserDefined(iter_val)) = self.iter_stack.last() {
823 let iter = *iter_val;
824 match self.try_call_dunder(iter, "__next__", &[], chunk, slots) {
825 Ok(Some(item)) => { self.push(item); }
826 Ok(None) => {
827 self.yield_from_value = Val::none();
828 self.iter_stack.pop();
829 if op as usize > n { return Err(cold_runtime("jump target out of bounds")); }
830 *ip = op as usize;
831 }
832 Err(VmErr::Raised(m)) if m == "StopIteration" || m.starts_with("StopIteration:") => {
833 // `raise StopIteration(v)` carries `v` as the yield-from value via the lifted instance.
834 self.yield_from_value = if m.starts_with("StopIteration:") {
835 match self.pending.exc_val {
836 Some(e) if e.is_heap() => match self.heap.get(e) {
837 HeapObj::ExcInstance(_, args) => args.first().copied().unwrap_or(Val::none()),
838 _ => Val::none(),
839 },
840 _ => Val::none(),
841 }
842 } else { Val::none() };
843 self.iter_stack.pop();
844 if op as usize > n { return Err(cold_runtime("jump target out of bounds")); }
845 *ip = op as usize;
846 }
847 Err(e) => return Err(e),
848 }
849 return Ok(());
850 }
851 // Split-borrow heap so the Range step can promote to LongInt.
852 let next = match self.iter_stack.last_mut() {
853 Some(f) => f.next_item(&mut self.heap)?,
854 None => None,
855 };
856 match next {

Callers 1

dispatchMethod · 0.80

Calls 11

cold_budgetFunction · 0.85
cold_runtimeFunction · 0.85
needs_gcMethod · 0.80
collectMethod · 0.80
resume_coroutineMethod · 0.80
pushMethod · 0.80
try_call_dunderMethod · 0.80
is_heapMethod · 0.80
next_itemMethod · 0.80
popMethod · 0.45
getMethod · 0.45

Tested by

no test coverage detected