luaur_vm/functions/
lua_v_concat.rs1use crate::functions::call_bin_tm::call_bin_tm;
5use crate::functions::lua_g_concaterror::lua_g_concaterror;
6use crate::functions::lua_s_buffinish::luaS_buffinish;
7use crate::functions::lua_s_bufstart::luaS_bufstart;
8use crate::functions::lua_s_newlstr::luaS_newlstr;
9use crate::macros::lua_buffersize::LUA_BUFFERSIZE;
10use crate::macros::lua_g_runerror::lua_g_runerror;
11use crate::macros::maxssize::MAXSSIZE;
12use crate::macros::setsvalue::setsvalue;
13use crate::macros::svalue::svalue;
14use crate::macros::tostring::tostring;
15use crate::macros::tsvalue::tsvalue;
16use crate::macros::ttisnumber::ttisnumber;
17use crate::macros::ttisstring::ttisstring;
18use crate::records::t_string::TString;
19use crate::type_aliases::lua_state::lua_State;
20use crate::type_aliases::stk_id::StkId;
21use crate::type_aliases::tms::TMS;
22use core::ffi::c_char;
23
24#[allow(non_snake_case)]
25pub unsafe fn lua_v_concat(L: *mut lua_State, mut total: i32, mut last: i32) {
26 loop {
27 let top: StkId = (*L).base.add((last + 1) as usize);
28 let mut n = 2; if !(ttisstring!(top.sub(2)) || ttisnumber!(top.sub(2))) || !tostring!(L, top.sub(1)) {
30 if call_bin_tm(L, top.sub(2), top.sub(1), top.sub(2), TMS::TM_CONCAT) == 0 {
31 lua_g_concaterror(L, top.sub(2), top.sub(1));
32 }
33 } else if (*tsvalue!(top.sub(1))).len == 0 {
34 let _ = tostring!(L, top.sub(2));
36 } else {
37 let mut tl = (*tsvalue!(top.sub(1))).len as usize;
39 n = 1;
41 while n < total && tostring!(L, top.sub((n + 1) as usize)) {
42 let l = (*tsvalue!(top.sub((n + 1) as usize))).len as usize;
43 if l > MAXSSIZE as usize - tl {
44 lua_g_runerror!(L, "string length overflow");
45 }
46 tl += l;
47 n += 1;
48 }
49
50 let mut buf = [0 as c_char; LUA_BUFFERSIZE as usize];
51 let mut ts: *mut TString = core::ptr::null_mut();
52
53 let buffer: *mut c_char = if tl < LUA_BUFFERSIZE as usize {
54 buf.as_mut_ptr()
55 } else {
56 ts = luaS_bufstart(L, tl);
57 (*ts).data.as_mut_ptr()
58 };
59
60 tl = 0;
62 let mut i = n;
63 while i > 0 {
64 let l = (*tsvalue!(top.sub(i as usize))).len as usize;
65 core::ptr::copy_nonoverlapping(svalue!(top.sub(i as usize)), buffer.add(tl), l);
66 tl += l;
67 i -= 1;
68 }
69
70 if tl < LUA_BUFFERSIZE as usize {
71 setsvalue!(L, top.sub(n as usize), luaS_newlstr(L, buffer, tl));
72 } else {
73 setsvalue!(L, top.sub(n as usize), luaS_buffinish(L, ts));
74 }
75 }
76 total -= n - 1; last -= n - 1;
78 if total <= 1 {
79 break; }
81 }
82}
83
84#[export_name = "luaV_concat"]
85pub unsafe extern "C" fn lua_v_concat_export(L: *mut lua_State, total: i32, last: i32) {
86 lua_v_concat(L, total, last);
87}
88
89#[allow(non_snake_case, unused_imports)]
90pub use lua_v_concat as luaV_concat;