`iter(x)`, eager flatten into a fresh List drained front-to-back by `next()`. Original isn't touched. Mirrors the universal ABI's `Op::Iter`. The 2-arg form `iter(callable, sentinel)` calls `callable()` until it returns `sentinel`, eagerly. */
(&mut self, argc: u16, chunk: &crate::modules::parser::SSAChunk, slots: &mut [Val])
| 375 | |
| 376 | /* `iter(x)`, eager flatten into a fresh List drained front-to-back by `next()`. Original isn't touched. Mirrors the universal ABI's `Op::Iter`. The 2-arg form `iter(callable, sentinel)` calls `callable()` until it returns `sentinel`, eagerly. */ |
| 377 | pub fn call_iter(&mut self, argc: u16, chunk: &crate::modules::parser::SSAChunk, slots: &mut [Val]) -> Result<(), VmErr> { |
| 378 | if argc == 2 { |
| 379 | let sentinel = self.pop()?; |
| 380 | let callable = self.pop()?; |
| 381 | let mut items: Vec<Val> = Vec::new(); |
| 382 | loop { |
| 383 | self.charge_step()?; // bound the call loop against the op budget |
| 384 | self.push(callable); |
| 385 | self.exec_call(0, chunk, slots)?; |
| 386 | let v = self.pop()?; |
| 387 | if eq_vals_with_heap(v, sentinel, &self.heap) { break; } |
| 388 | if items.len() >= self.heap.limit() { return Err(cold_heap()); } |
| 389 | items.push(v); |
| 390 | } |
| 391 | return self.alloc_and_push_list(items); |
| 392 | } |
| 393 | if argc != 1 { return Err(cold_type("iter() takes 1 or 2 arguments")); } |
| 394 | let o = self.pop()?; |
| 395 | let items = self.iter_to_vec_general(o)?; |
| 396 | self.alloc_and_push_list(items) |
| 397 | } |
| 398 | |
| 399 | pub fn call_next(&mut self, argc: u16, chunk: &crate::modules::parser::SSAChunk, slots: &mut [Val]) -> Result<(), VmErr> { |
| 400 | if argc == 0 || argc > 2 { return Err(cold_type("next() takes 1 or 2 arguments")); } |
no test coverage detected