luaur_code_gen/functions/
append_vm_constant.rs1extern crate alloc;
2
3use crate::functions::append::append;
4use crate::functions::format_g::format_g;
5use crate::functions::is_printable_string_constant::is_printable_string_constant;
6use alloc::string::String;
7use core::ffi::{c_char, c_uint};
8use luaur_vm::macros::gco_2_ts::gco2ts;
9use luaur_vm::macros::getstr::getstr;
10use luaur_vm::macros::lua_vector_size::LUA_VECTOR_SIZE;
11use luaur_vm::records::g_cheader::GCheader;
12use luaur_vm::records::t_string::TString;
13use luaur_vm::type_aliases::proto::Proto;
14
15const LUA_TNIL: i32 = 0;
17const LUA_TBOOLEAN: i32 = 1;
18const LUA_TNUMBER: i32 = 3;
19const LUA_TINTEGER: i32 = 4;
20const LUA_TVECTOR: i32 = 5;
21const LUA_TSTRING: i32 = 6;
22
23const K_MAX_STRING_CONSTANT_PRINT_LENGTH: c_uint = 16;
24
25#[repr(C)]
28struct TStringHeader {
29 hdr: GCheader,
30 _padding1: [c_char; 1],
31 atom: i16,
32 _padding2: [c_char; 2],
33 next: *mut TString,
34 hash: c_uint,
35 len: c_uint,
36 data: [c_char; 1],
37}
38
39pub fn append_vm_constant(result: &mut String, proto: *mut Proto, index: i32) {
40 unsafe {
41 let constant = *(*proto).k.add(index as usize);
42
43 if constant.tt == LUA_TNIL {
44 append(result, format_args!("nil"));
45 } else if constant.tt == LUA_TBOOLEAN {
46 append(
47 result,
48 format_args!(
49 "{}",
50 if constant.value.b != 0 {
51 "true"
52 } else {
53 "false"
54 }
55 ),
56 );
57 } else if constant.tt == LUA_TNUMBER {
58 let n = constant.value.n;
59 if n != n {
60 append(result, format_args!("nan"));
61 } else {
62 result.push_str(&format_g(n, 17));
64 }
65 } else if constant.tt == LUA_TINTEGER {
66 append(result, format_args!("{}i", constant.value.l as i64));
67 } else if constant.tt == LUA_TSTRING {
68 let str_ts = gco2ts!(constant.value.gc) as *const _ as *const TString;
69 let data = getstr(str_ts);
70 let len = (*(str_ts as *const TStringHeader)).len;
71
72 if is_printable_string_constant(data, len as usize) {
73 let n = if len < K_MAX_STRING_CONSTANT_PRINT_LENGTH {
74 len
75 } else {
76 K_MAX_STRING_CONSTANT_PRINT_LENGTH
77 } as usize;
78 let bytes = core::slice::from_raw_parts(data as *const u8, n);
79 let text = String::from_utf8_lossy(bytes);
80
81 if len < K_MAX_STRING_CONSTANT_PRINT_LENGTH {
82 append(result, format_args!("'{}'", text));
83 } else {
84 append(result, format_args!("'{}'...", text));
85 }
86 }
87 } else if constant.tt == LUA_TVECTOR {
88 let v = &constant.value as *const _ as *const f32;
91
92 if LUA_VECTOR_SIZE == 4 {
93 if *v.add(3) != 0.0 {
94 append(
95 result,
96 format_args!(
97 "{}, {}, {}, {}",
98 format_g(*v.add(0) as f64, 9),
99 format_g(*v.add(1) as f64, 9),
100 format_g(*v.add(2) as f64, 9),
101 format_g(*v.add(3) as f64, 9)
102 ),
103 );
104 } else {
105 append(
106 result,
107 format_args!(
108 "{}, {}, {}",
109 format_g(*v.add(0) as f64, 9),
110 format_g(*v.add(1) as f64, 9),
111 format_g(*v.add(2) as f64, 9)
112 ),
113 );
114 }
115 } else {
116 append(
117 result,
118 format_args!(
119 "{}, {}, {}",
120 format_g(*v.add(0) as f64, 9),
121 format_g(*v.add(1) as f64, 9),
122 format_g(*v.add(2) as f64, 9)
123 ),
124 );
125 }
126 }
127 }
128}