Implements the `AllocArray` opcode.
(&mut self, instr: u32, heap: &mut Heap)
| 613 | |
| 614 | /// Implements the `AllocArray` opcode. |
| 615 | pub(super) fn do_alloc_array(&mut self, instr: u32, heap: &mut Heap) { |
| 616 | let (dest, packed, first_dim_reg) = bytecode::parse_alloc_array(instr); |
| 617 | let subtype = packed.subtype(); |
| 618 | let ndims = usize::from(packed.ndims()); |
| 619 | |
| 620 | let (_, first_idx) = first_dim_reg.to_parts(); |
| 621 | let mut dimensions = Vec::with_capacity(ndims); |
| 622 | let mut total: usize = 1; |
| 623 | for i in 0..ndims { |
| 624 | let dim_reg = Register::local(first_idx + i as u8).unwrap(); |
| 625 | let dim = match usize::try_from(self.get_reg(dim_reg) as i32) { |
| 626 | Ok(0) | Err(_) => { |
| 627 | self.set_exception(format!("Dimension {} must be positive", i)); |
| 628 | return; |
| 629 | } |
| 630 | Ok(n) => n, |
| 631 | }; |
| 632 | dimensions.push(dim); |
| 633 | total *= dim; |
| 634 | } |
| 635 | |
| 636 | let values = match subtype { |
| 637 | ExprType::Boolean | ExprType::Double | ExprType::Integer => { |
| 638 | vec![0; total] |
| 639 | } |
| 640 | ExprType::Text => vec![heap.empty_text_ptr(); total], |
| 641 | }; |
| 642 | let array = ArrayData { dimensions, values }; |
| 643 | let ptr = match heap.push(HeapDatum::Array(array)) { |
| 644 | Ok(ptr) => ptr, |
| 645 | Err(e) => { |
| 646 | self.set_exception(e.to_string()); |
| 647 | return; |
| 648 | } |
| 649 | }; |
| 650 | self.set_reg(dest, ptr); |
| 651 | self.pc += 1; |
| 652 | } |
| 653 | |
| 654 | /// Implements the `BitwiseAnd` opcode. |
| 655 | pub(super) fn do_bitwise_and(&mut self, instr: u32) { |