Skip to main content

luaur_bytecode/methods/
bytecode_graph_parser_find_producers_up_to_top.rs

1use crate::records::bc_op::BcOp;
2use crate::records::bytecode_graph_parser::BytecodeGraphParser;
3use crate::type_aliases::reg::Reg;
4
5use alloc::vec::Vec;
6use luaur_common::macros::luau_assert::LUAU_ASSERT;
7
8impl<'a> BytecodeGraphParser<'a> {
9    pub fn find_producers_up_to_top(&mut self, block: BcOp, reg: Reg) -> Vec<BcOp> {
10        // We assume it called only for search of var return calls.
11        LUAU_ASSERT!(block.index < self.producers.len() as u32);
12
13        let multi_return_start;
14        let multi_return;
15        {
16            let block_producers = &self.producers[block.index as usize];
17            LUAU_ASSERT!(
18                block_producers.multiReturn.kind == crate::enums::bc_op_kind::BcOpKind::Inst
19            );
20            multi_return_start = block_producers.multiReturnStart;
21            multi_return = block_producers.multiReturn;
22        }
23
24        // So we need to find all producers from reg to blockProducers.multiReturnStart.
25        let mut res = Vec::new();
26        res.reserve(multi_return_start as usize - reg as usize + 1);
27
28        let mut r = reg;
29        while r < multi_return_start {
30            let static_reg_op = self.find_producer_bc_op_reg(block, r);
31            LUAU_ASSERT!(static_reg_op.is_some());
32            res.push(static_reg_op.unwrap());
33            r += 1;
34        }
35
36        res.push(multi_return);
37
38        // multireturn is consumed, clean it up
39        let block_producers = &mut self.producers[block.index as usize];
40        block_producers.multiReturn = BcOp::new();
41        block_producers.multiReturnStart = 0xFF;
42
43        res
44    }
45}