Skip to main content

luaur_reduce_cli/methods/
reducer_delete_child_statements_reduce.rs

1use crate::enums::test_result::TestResult;
2use crate::records::reducer::Reducer;
3use alloc::vec::Vec;
4use core::cmp;
5use luaur_ast::records::ast_array::AstArray;
6use luaur_ast::records::ast_stat::AstStat;
7use luaur_ast::records::ast_stat_block::AstStatBlock;
8
9impl Reducer {
10    pub fn delete_child_statements_ast_stat_block_usize(
11        &mut self,
12        block: *mut AstStatBlock,
13        chunk_count: usize,
14    ) -> (bool, usize) {
15        unsafe {
16            if (*block).body.size == 0 {
17                return (false, chunk_count);
18            }
19
20            let mut current_chunk_count = chunk_count;
21            let block_size = (*block).body.size;
22
23            loop {
24                let permutations = self.generate_spans(block_size, current_chunk_count);
25                for (span1, span2) in permutations {
26                    let temp_statements = self.pruned_span(block, span1, span2);
27                    let mut backup_body = (*block).body;
28
29                    let mut new_body = AstArray {
30                        data: temp_statements.as_ptr() as *mut *mut AstStat,
31                        size: temp_statements.len(),
32                    };
33
34                    core::mem::swap(&mut (*block).body, &mut new_body);
35
36                    let result = self.run();
37                    if result == TestResult::BugFound {
38                        // The bug still reproduces without the statements we've culled. Commit.
39                        (*block).body.data = self.reallocate_statements(&temp_statements);
40                        (*block).body.size = temp_statements.len();
41                        return (true, cmp::max(2, current_chunk_count.saturating_sub(1)));
42                    } else {
43                        core::mem::swap(&mut (*block).body, &mut new_body);
44                    }
45                }
46
47                current_chunk_count *= 2;
48                if current_chunk_count > block_size {
49                    break;
50                }
51            }
52
53            (false, block_size)
54        }
55    }
56}