luaur_compiler/methods/
compiler_compile_stat_while.rs1use crate::records::compiler::Compiler;
2use luaur_ast::records::ast_node::AstNode;
3use luaur_ast::records::ast_stat_while::AstStatWhile;
4use luaur_common::enums::luau_opcode::LuauOpcode;
5
6impl Compiler {
7 pub fn compile_stat_while(&mut self, stat: *mut AstStatWhile) {
8 unsafe {
9 let stat_ref = &*stat;
10
11 if self.is_constant_false(stat_ref.condition) {
13 return;
14 }
15
16 let old_jumps = self.loop_jumps.len();
17 let old_locals = self.local_stack.len();
18
19 self.loops.push(crate::records::r#loop::Loop {
20 local_offset: old_locals,
21 local_offset_continue: old_locals,
22 continue_used: core::ptr::null_mut(),
23 });
24 self.has_loops = true;
25
26 let loop_label = (*self.bytecode).emit_label();
27
28 let mut else_jump = Vec::new();
29 self.compile_condition_value(
30 stat_ref.condition,
31 core::ptr::null(),
32 &mut else_jump,
33 false,
34 );
35
36 self.compile_stat(stat_ref.body as *mut luaur_ast::records::ast_stat::AstStat);
37
38 let cont_label = (*self.bytecode).emit_label();
39 let back_label = (*self.bytecode).emit_label();
40
41 self.set_debug_line_ast_node(stat as *mut AstNode);
42
43 (*self.bytecode).emit_ad(LuauOpcode::LOP_JUMPBACK, 0, 0);
45
46 let end_label = (*self.bytecode).emit_label();
47
48 self.patch_jump(stat as *mut AstNode, back_label, loop_label);
49 self.patch_jumps(stat as *mut AstNode, &mut else_jump, end_label);
50
51 self.patch_loop_jumps(stat as *mut AstNode, old_jumps, end_label, cont_label);
52 self.loop_jumps.resize(
53 old_jumps,
54 crate::records::loop_jump::LoopJump {
55 r#type: crate::enums::type_compiler::Type::Break,
56 label: 0,
57 },
58 );
59
60 self.loops.pop();
61 }
62 }
63}