Materialise an iterable to a list, strings -> chars, ranges eager, coroutines drained.
(&mut self, argc: u16, chunk: &crate::modules::parser::SSAChunk, slots: &mut [Val])
| 514 | |
| 515 | // Materialise an iterable to a list, strings -> chars, ranges eager, coroutines drained. |
| 516 | pub fn call_list(&mut self, argc: u16, chunk: &crate::modules::parser::SSAChunk, slots: &mut [Val]) -> Result<(), VmErr> { |
| 517 | if argc == 0 { return self.alloc_and_push_list(Vec::new()); } // `list()` is the empty list. |
| 518 | let o = self.pop()?; |
| 519 | // user-defined iterable wins over the built-in dispatch. |
| 520 | if let Some(items) = self.iter_to_vec_op(o, chunk, slots)? { |
| 521 | return self.alloc_and_push_list(items); |
| 522 | } |
| 523 | if o.is_heap() { |
| 524 | match self.heap.get(o) { |
| 525 | HeapObj::Str(s) => { |
| 526 | let s = s.clone(); |
| 527 | let items = self.str_to_char_vals(&s)?; |
| 528 | return self.alloc_and_push_list(items); |
| 529 | } |
| 530 | HeapObj::Coroutine(..) => { |
| 531 | // Keep the coroutine and its yielded values rooted on the VM stack; each resume can allocate and trigger GC. |
| 532 | self.push(o); |
| 533 | let base = self.stack.len(); |
| 534 | loop { |
| 535 | self.charge_step()?; |
| 536 | let v = self.resume_coroutine(o)?; |
| 537 | if !self.yielded { break; } |
| 538 | self.yielded = false; |
| 539 | self.push(v); |
| 540 | } |
| 541 | // A shorter stack must not panic split_off; clamp. |
| 542 | let out = self.stack.split_off(base.min(self.stack.len())); |
| 543 | self.pop()?; // drop the rooted coroutine |
| 544 | return self.alloc_and_push_list(out); |
| 545 | } |
| 546 | _ => {} |
| 547 | } |
| 548 | } |
| 549 | let items = self.extract_iter(o, true)?; |
| 550 | self.alloc_and_push_list(items) |
| 551 | } |
| 552 | |
| 553 | pub fn call_tuple(&mut self, argc: u16, chunk: &crate::modules::parser::SSAChunk, slots: &mut [Val]) -> Result<(), VmErr> { |
| 554 | if argc == 0 { return self.alloc_and_push_tuple(Vec::new()); } // `tuple()` is the empty tuple. |
no test coverage detected