Skip to main content

rs_luau/ffi/
luau.rs

1use std::{
2    ffi::{c_char, c_double, c_float, c_int, c_uchar, c_uint, c_void},
3    marker::{PhantomData, PhantomPinned},
4    ptr::null_mut,
5};
6
7use super::luauconf::LUAI_MAXCSTACK;
8
9pub const LUA_MULTRET: c_int = -1;
10pub const LUA_REGISTRYINDEX: c_int = -LUAI_MAXCSTACK - 2000;
11pub const LUA_ENVIRONINDEX: c_int = -LUAI_MAXCSTACK - 2001;
12pub const LUA_GLOBALSINDEX: c_int = -LUAI_MAXCSTACK - 2002;
13
14#[inline]
15pub const fn lua_upvalueindex(i: c_int) -> c_int {
16    LUA_GLOBALSINDEX - i
17}
18
19#[inline]
20pub const fn lua_ispseudo(i: c_int) -> bool {
21    i <= LUA_REGISTRYINDEX
22}
23
24// thread status; 0 is OK
25#[repr(C)]
26#[derive(Debug)]
27#[allow(non_camel_case_types)]
28pub enum LuauStatus {
29    /// OK status
30    LUA_OK = 0,
31    /// Yielded
32    LUA_YIELD,
33    /// Errored on a runtime error
34    LUA_ERRRUN,
35    #[deprecated = "legacy error code, preserved for compatibility"]
36    LUA_ERRSYNTAX,
37    /// Errored on a memory allocation failure
38    LUA_ERRMEM,
39    /// Errored in error handling
40    LUA_ERRERR,
41    /// Yielded on a breakpoint
42    LUA_BREAK,
43}
44
45#[repr(C)]
46#[allow(non_camel_case_types)]
47pub enum CoroutineStatus {
48    /// The coroutine is running
49    LUA_CORUN = 0,
50    /// The coroutine is suspsneded
51    LUA_COSUS,
52    /// The couroutine is 'normal' (resumed another coroutine)
53    LUA_CONOR,
54    /// The coroutine finished successfully
55    LUA_COFIN,
56    /// The coroutine finished with an error
57    LUA_COERR,
58}
59
60/// A raw Luau state associated with a thread.
61#[repr(C)]
62pub struct _LuaState {
63    _data: [u8; 0],
64    _marker: PhantomData<(*mut u8, PhantomPinned)>,
65}
66
67#[repr(transparent)]
68pub struct Tag(pub c_int);
69
70/// Type for native C functions that can be passed to Luau.
71pub type CFunction = unsafe extern "C-unwind" fn(*mut _LuaState) -> c_int;
72/// Type for unrolling across the stack
73pub type LuaContinuation = unsafe extern "C-unwind" fn(*mut _LuaState, c_int) -> c_int;
74/// Type for Luau allocation functions
75pub type LuaAlloc = unsafe extern "C-unwind" fn(
76    ud: *mut c_void,
77    ptr: *mut c_void,
78    osize: usize,
79    nsize: usize,
80) -> *mut c_void;
81/// Type for Luau dtor functions
82pub type LuaDestructor = unsafe extern "C-unwind" fn(*mut _LuaState, *mut c_void);
83
84/// Luau type value
85#[repr(C)]
86#[derive(Debug, PartialEq, PartialOrd)]
87#[allow(non_camel_case_types)]
88pub enum LuauType {
89    LUA_TNONE = -1,
90    LUA_TNIL = 0,     // must be 0 due to lua_isnoneornil
91    LUA_TBOOLEAN = 1, // must be 1 due to l_isfalse
92
93    LUA_TLIGHTUSERDATA,
94    LUA_TNUMBER,
95    LUA_TVECTOR,
96
97    LUA_TSTRING, // all types above this must be value types, all types below this must be GC types - see iscollectable
98
99    LUA_TTABLE,
100    LUA_TFUNCTION,
101    LUA_TUSERDATA,
102    LUA_TTHREAD,
103    LUA_TBUFFER,
104
105    // values below this line are used in GCObject tags but may never show up in TValue type tags
106    LUA_TPROTO,
107    LUA_TUPVAL,
108    LUA_TDEADKEY,
109}
110
111pub const LUA_T_COUNT: c_int = LuauType::LUA_TPROTO as c_int;
112
113/// Type of numbers in Luau
114pub type LuaNumber = c_double;
115
116/// Type for integer functions
117pub type LuaInteger = c_int;
118
119/// Unsigned integer type
120pub type LuaUnsigned = c_uint;
121
122extern "C-unwind" {
123    /// Creates a new independent state and returns its main thread.
124    /// Returns NULL if it cannot create the state (due to lack of memory).
125    /// The argument f is the allocator function; Luau will do all memory allocation for this state through this function (see LuaAlloc).
126    /// The second argument, ud, is an opaque pointer that Luau passes to the allocator in every call.
127    pub fn lua_newstate(f: LuaAlloc, ud: *mut c_void) -> *mut _LuaState;
128
129    /// Close all active to-be-closed variables in the main thread, release all objects in the given Luau state (calling the corresponding garbage-collection metamethods, if any), and frees all dynamic memory used by this state.
130    ///
131    /// On several platforms, you may not need to call this function, because all resources are naturally released when the host program ends.
132    /// On the other hand, long-running programs that create multiple states, such as daemons or web servers, will probably need to close states as soon as they are not needed.
133    pub fn lua_close(state: *mut _LuaState);
134
135    /// Creates a new thread, pushes it on the stack, and returns a pointer to a lua_State that represents this new thread.
136    /// The new thread returned by this function shares with the original thread its global environment, but has an independent execution stack.
137    ///
138    /// Threads are subject to garbage collection, like any Luau object.
139    pub fn lua_newthread(state: *mut _LuaState) -> *mut _LuaState;
140
141    /// Retrieves the main thread for a thread state
142    pub fn lua_mainthread(state: *mut _LuaState) -> *mut _LuaState;
143
144    /// Resets a thread, cleaning its call stack and closing all pending to-be-closed variables.
145    /// In case of error, leaves the error object on the top of the stack.
146    pub fn lua_resetthread(state: *mut _LuaState);
147
148    /// Determines if a thread is reset
149    pub fn lua_isthreadreset(state: *mut _LuaState) -> c_int;
150}
151
152extern "C-unwind" {
153    /// Converts the acceptable index idx into an equivalent absolute index (that is, one that does not depend on the stack size).
154    pub fn lua_absindex(state: *mut _LuaState, idx: c_int) -> c_int;
155
156    /// Returns the index of the top element in the stack.
157    /// Because indices start at 1, this result is equal to the number of elements in the stack; in particular, 0 means an empty stack.
158    pub fn lua_gettop(state: *mut _LuaState) -> c_int;
159
160    /// Accepts any index, or 0, and sets the stack top to this index. If the new top is greater than the old one, then the new elements are filled with nil. If index is 0, then all stack elements are removed.
161    pub fn lua_settop(state: *mut _LuaState, idx: c_int);
162
163    /// Pushes a copy of the element at the given index onto the stack.
164    pub fn lua_pushvalue(state: *mut _LuaState, idx: c_int);
165
166    /// Removes the element at the given valid index, shifting down the elements above this index to fill the gap.
167    pub fn lua_remove(state: *mut _LuaState, idx: c_int);
168
169    /// Moves the top element into the given valid index, shifting up the elements above this index to open space.
170    pub fn lua_insert(state: *mut _LuaState, idx: c_int);
171
172    /// Moves the top element into the given valid index without shifting any element (therefore replacing the value at that given index), and then pops the top element.
173    pub fn lua_replace(state: *mut _LuaState, idx: c_int);
174
175    /// Ensures that the stack has space for at least n extra elements, that is, that you can safely push up to n values into it.
176    /// Will throw if it cannot perform an allocation or will return false if would cause the stack to be greater than a fixed maximum size.
177    /// This function never shrinks the stack; if the stack already has space for the extra elements, it is left unchanged.
178    pub fn lua_checkstack(state: *mut _LuaState, sz: c_int) -> c_int;
179
180    /// Same as lua_checkstack but allows for unlimited stack frames
181    pub fn lua_rawcheckstack(state: *mut _LuaState, sz: c_int);
182}
183
184extern "C-unwind" {
185    /// Exchange values between different threads of the same state.
186    ///
187    /// This function pops n values from the stack from, and pushes them onto the stack to.
188    pub fn lua_xmove(from: *mut _LuaState, to: *mut _LuaState, idx: c_int);
189
190    /// Exchange values between different threads of the same state.
191    ///
192    /// This function copies n values from the stack from, and pushes them onto the stack to.
193    pub fn lua_xpush(from: *mut _LuaState, to: *mut _LuaState, idx: c_int);
194}
195
196extern "C-unwind" {
197    /// Returns 1 if the value at the given index is a number or a string convertible to a number, and 0 otherwise.
198    pub fn lua_isnumber(state: *mut _LuaState, idx: c_int) -> c_int;
199
200    /// Returns 1 if the value at the given index is a string or a number (which is always convertible to a string), and 0 otherwise.
201    pub fn lua_isstring(state: *mut _LuaState, idx: c_int) -> c_int;
202
203    /// Returns 1 if the value at the given index is a C function, and 0 otherwise.
204    pub fn lua_iscfunction(state: *mut _LuaState, idx: c_int) -> c_int;
205
206    /// Returns 1 if the value at the given index is a Luau function, and 0 otherwise.
207    pub fn lua_isLfunction(state: *mut _LuaState, idx: c_int) -> c_int;
208
209    /// Returns 1 if the value at the given index is a userdata (either full or light), and 0 otherwise.
210    pub fn lua_isuserdata(state: *mut _LuaState, idx: c_int) -> c_int;
211
212    /// Returns the type of the value in the given valid index, or LUA_TNONE for a non-valid but acceptable index.
213    pub fn lua_type(state: *mut _LuaState, idx: c_int) -> LuauType;
214
215    /// Returns the name of the type encoded by the value tp, which must be one the values returned by lua_type.
216    pub fn lua_typename(state: *mut _LuaState, tp: LuauType) -> *const c_char;
217}
218
219extern "C-unwind" {
220    /// Runs a equality check for two values at 2 indexes, may invoke metamethods
221    pub fn lua_equal(state: *mut _LuaState, idx1: c_int, idx2: c_int) -> c_int;
222
223    /// Runs a equality check for two values at 2 indexes, will not invoke metamethods
224    pub fn lua_rawequal(state: *mut _LuaState, idx1: c_int, idx2: c_int) -> c_int;
225
226    /// Runs a lessthan check for two values at 2 indexes, may invoke metamethods
227    pub fn lua_lessthan(state: *mut _LuaState, idx1: c_int, idx2: c_int) -> c_int;
228}
229
230extern "C-unwind" {
231    /// Converts the Luau value at the given index to the type LuaNumber.
232    /// The Luau value must be a number or a string convertible to a number; otherwise returns 0.
233    ///
234    /// If isnum is not NULL, its referent is assigned a boolean value that indicates whether the operation succeeded.
235    pub fn lua_tonumberx(state: *mut _LuaState, idx: c_int, isnum: *mut c_int) -> LuaNumber;
236
237    /// Converts the Luau value at the given index to the signed integral type LuaInteger.
238    /// The Luau value must be an integer, or a number or string convertible to an integer; otherwise, lua_tointegerx returns 0.
239    ///
240    /// If isnum is not NULL, its referent is assigned a boolean value that indicates whether the operation succeeded.
241    pub fn lua_tointegerx(state: *mut _LuaState, idx: c_int, isnum: *mut c_int) -> LuaInteger;
242
243    /// Converts the Luau value at the given index to the unsigned integral type LuaUnsigned.
244    /// The Luau value must be an integer, or a number or string convertible to an integer; otherwise, lua_tounsignedx returns 0.
245    ///
246    /// If isnum is not NULL, its referent is assigned a boolean value that indicates whether the operation succeeded.
247    pub fn lua_tounsignedx(state: *mut _LuaState, idx: c_int, isnum: *mut c_int) -> LuaUnsigned;
248
249    /// Gets the Luau value's vector pointer.
250    ///
251    /// If the value is not a vector then will return NULL
252    pub fn lua_tovector(state: *mut _LuaState, idx: c_int) -> *const c_float;
253
254    /// Converts the Luau value at the given index to a C boolean value (0 or 1).
255    /// Like all tests in Luau, lua_toboolean returns true for any Luau value different from false and nil; otherwise it returns false. (If you want to accept only actual boolean values, use lua_isboolean to test the value's type.)
256    pub fn lua_toboolean(state: *mut _LuaState, idx: c_int) -> c_int;
257
258    /// Converts the Luau value at the given index to a C string. If len is not NULL, it sets *len with the string length.
259    /// The Luau value must be a string or a number; otherwise, the function returns NULL.
260    /// If the value is a number, then lua_tolstring also changes the actual value in the stack to a string. (This change confuses lua_next when lua_tolstring is applied to keys during a table traversal.)
261    /// lua_tolstring returns a pointer to a string inside the Luau state. This string always has a zero ('\0') after its last character (as in C), but can contain other zeros in its body.
262    pub fn lua_tolstring(state: *mut _LuaState, idx: c_int, len: *mut usize) -> *const c_char;
263
264    /// Retrieves a const char pointer and updates an int pointer to the atom returned from the useratom callback the atom pointer is not NULL
265    pub fn lua_tostringatom(state: *mut _LuaState, idx: c_int, atom: *mut c_int) -> *const c_char;
266
267    /// Gets a const char poitner and an atom from the current namecall string if its not NULL
268    pub fn lua_namecallatom(state: *mut _LuaState, atom: *mut c_int) -> *const c_char;
269
270    /// Performs a luau length operator which retrieves the length of values (may invoke metamethods)
271    pub fn lua_objlen(state: *mut _LuaState, idx: c_int) -> c_int;
272
273    /// Converts a value at the given index to a C function. That value must be a C function; otherwise, returns NULL.
274    pub fn lua_tocfunction(state: *mut _LuaState, idx: c_int) -> c_int;
275
276    /// Converts a value at the given index to the lightuserdata's C pointer. That value must be a lightuserdata; otherwise, returns NULL.
277    pub fn lua_tolightuserdata(state: *mut _LuaState, idx: c_int) -> *mut c_void;
278
279    /// Converts a value at the given index to the lightuserdata's C pointer. That value must be a lightuserdata with the proper tag; otherwise, returns NULL.
280    pub fn lua_tolightuserdatatagged(state: *mut _LuaState, idx: c_int, tag: Tag) -> *mut c_void;
281
282    /// If the value at the given index is a full userdata, returns its memory-block address.
283    /// If the value is a light userdata, returns its value (a pointer). Otherwise, returns NULL.
284    pub fn lua_touserdata(state: *mut _LuaState, idx: c_int) -> *mut c_void;
285
286    /// If the value at the given index is a full userdata and has a correct tag, returns its memory-block address.
287    /// Otherwise, returns NULL.
288    pub fn lua_touserdatatagged(state: *mut _LuaState, idx: c_int, tag: Tag) -> *mut c_void;
289
290    /// Returns a full userdata's tag or -1 if there is no tag
291    pub fn lua_userdatatag(state: *mut _LuaState, idx: c_int) -> Tag;
292
293    /// Returns a light userdata's tag or -1 if there is no tag
294    pub fn lua_lightuserdatatag(state: *mut _LuaState, idx: c_int) -> Tag;
295
296    /// Converts the value at the given index to a Luau thread (represented as lua_State*).
297    /// This value must be a thread; otherwise, the function returns NULL.
298    pub fn lua_tothread(state: *mut _LuaState, idx: c_int) -> *mut _LuaState;
299
300    /// Returns the buffer pointer and updates the value at the len pointer if its not NULL
301    pub fn lua_tobuffer(state: *mut _LuaState, idx: c_int, len: *mut usize) -> *mut c_void;
302    /// Converts the value at the given index to a generic C pointer (void*). The value can be a userdata, a table, a thread, a string, or a function; otherwise, lua_topointer returns NULL. Different objects will give different pointers. There is no way to convert the pointer back to its original value.
303    ///
304    /// Typically this function is used only for hashing and debug information.
305    pub fn lua_topointer(state: *mut _LuaState, idx: c_int) -> *const c_void;
306}
307
308extern "C-unwind" {
309    /// Pushes a nil value onto the stack
310    pub fn lua_pushnil(state: *mut _LuaState);
311
312    /// Pushes a double with value n onto the stack.
313    pub fn lua_pushnumber(state: *mut _LuaState, n: LuaNumber);
314
315    /// Pushes an integer with value n onto the stack.
316    pub fn lua_pushinteger(state: *mut _LuaState, n: LuaInteger);
317
318    /// Pushes an unsigned integer with value n onto the stack.
319    pub fn lua_pushunsigned(state: *mut _LuaState, n: LuaUnsigned);
320
321    #[cfg(feature = "luau_vector4")]
322    /// Pushes a 4 value Luau vector onto the stack
323    pub fn lua_pushvector(state: *mut _LuaState, x: c_float, y: c_float, z: c_float, w: c_float);
324
325    #[cfg(not(feature = "luau_vector4"))]
326    /// Pushes a 3 value Luau vector onto the stack
327    pub fn lua_pushvector(state: *mut _LuaState, x: c_float, y: c_float, z: c_float);
328
329    /// Pushes the string pointed to by s with size len onto the stack.
330    /// Luau will make or reuse an internal copy of the given string, so the memory at s can be freed or reused immediately after the function returns.
331    /// The string can contain any binary data, including embedded zeros.
332    pub fn lua_pushlstring(state: *mut _LuaState, s: *const c_char, l: usize);
333
334    /// Pushes the zero-terminated string pointed to by s onto the stack.
335    /// Luau will make or reuse an internal copy of the given string, so the memory at s can be freed or reused immediately after the function returns.
336    pub fn lua_pushstring(state: *mut _LuaState, s: *const c_char);
337
338    // requires va_list, add when stable
339    // fn lua_pushvfstring(state: *mut lua_State, fmt: *const c_char, argp: std::ffi::VaList) -> *const c_char;
340
341    /// Pushes onto the stack a formatted string and returns a pointer to this string. This internally uses `vsnprintf` so all formatting applies.
342    ///
343    /// This function may raise errors due to memory overflow or an invalid conversion specifier.
344    pub fn lua_pushfstringL(state: *mut _LuaState, fmt: *const c_char, ...) -> *const c_char;
345
346    /// Pushes a new C closure onto the stack.
347    ///
348    /// When a C function is created, it is possible to associate some values with it, thus creating a C closure; these values are then accessible to the function whenever it is called.
349    /// To associate values with a C function, first these values should be pushed onto the stack (when there are multiple values, the first value is pushed first).
350    /// Then lua_pushcclosurek is called to create and push the C function onto the stack, with the argument n telling how many values should be associated with the function.
351    /// lua_pushcclosurek also pops these values from the stack.
352    ///
353    /// The maximum value for n is 255.
354    ///
355    /// The continuation function is invoked when resumes acrossing it
356    pub fn lua_pushcclosurek(
357        state: *mut _LuaState,
358        function: CFunction,
359        debugname: *const c_char,
360        nup: c_int,
361        cont: Option<LuaContinuation>,
362    );
363
364    /// Pushes a boolean value with value b onto the stack.
365    pub fn lua_pushboolean(state: *mut _LuaState, b: c_int);
366
367    /// Pushes the thread represented by L onto the stack. Returns 1 if this thread is the main thread of its state.
368    pub fn lua_pushthread(state: *mut _LuaState) -> c_int;
369}
370
371extern "C-unwind" {
372    /// Pushes a new light userdata with a specified tag
373    pub fn lua_pushlightuserdatatagged(state: *mut _LuaState, p: *mut c_void, tag: Tag);
374
375    /// Creates a new sized userdata with a specified tag
376    pub fn lua_newuserdatatagged(state: *mut _LuaState, sz: usize, tag: Tag) -> *mut c_void;
377
378    /// Creates a new userdata object with a destructor callback which is invoked on GC
379    pub fn lua_newuserdatadtor(state: *mut _LuaState, sz: usize, dtor: LuaDestructor);
380}
381
382extern "C-unwind" {
383    /// Create a new luau buffer of a specified size
384    ///
385    /// Will error if it cannot be created
386    pub fn lua_newbuffer(state: *mut _LuaState, sz: usize) -> *mut c_void;
387}
388
389extern "C-unwind" {
390    /// Pushes onto the stack the value t[k], where t is the value at the given index and k is the value on the top of the stack.
391    ///
392    /// This function pops the key from the stack, pushing the resulting value in its place.
393    /// As in Luau, this function may trigger a metamethod for the "index" event.
394    ///
395    /// Returns the type of the pushed value.
396    pub fn lua_gettable(state: *mut _LuaState, idx: c_int) -> LuauType;
397
398    /// Pushes onto the stack the value t[k], where t is the value at the given index.
399    /// As in Luau, this function may trigger a metamethod for the "index" event.
400    ///
401    /// Returns the type of the pushed value.
402    pub fn lua_getfield(state: *mut _LuaState, idx: c_int, k: *const c_char) -> LuauType;
403
404    /// Pushes onto the stack the value t[k], where t is the value at the given index.
405    /// This function will not trigger a metamethod for the "index" event.
406    ///
407    /// Returns the type of the pushed value.
408    pub fn lua_rawgetfield(state: *mut _LuaState, idx: c_int, k: *const c_char) -> LuauType;
409
410    /// Similar to lua_gettable, but does a raw access (i.e., without metamethods). The value at index must be a table.
411    pub fn lua_rawget(state: *mut _LuaState, idx: c_int) -> LuauType;
412
413    /// Pushes onto the stack the value t[n], where t is the table at the given index. The access is raw, that is, it does not use the __index metavalue.
414    ///
415    /// Returns the type of the pushed value.
416    pub fn lua_rawgeti(state: *mut _LuaState, idx: c_int, idx: c_int) -> LuauType;
417
418    /// Creates a table of a specified array sized and a specified size of the associative portion
419    pub fn lua_createtable(state: *mut _LuaState, narr: c_int, nrec: c_int);
420}
421
422extern "C-unwind" {
423    /// Sets a table at the index to be readonly or not with the enabled argument
424    pub fn lua_setreadonly(state: *mut _LuaState, idx: c_int, enabled: c_int);
425
426    /// Returns if a table at the index is readonly
427    pub fn lua_getreadonly(state: *mut _LuaState, idx: c_int) -> c_int;
428
429    /// Sets the safeenv parameter which toggles specific optimizations, this should be called if environment mutation is done in a way which would affect code
430    pub fn lua_setsafeenv(state: *mut _LuaState, idx: c_int, enabled: c_int);
431}
432
433extern "C-unwind" {
434    /// If the value at the given index has a metatable, the function pushes that metatable onto the stack and returns 1.
435    /// Otherwise, the function returns 0 and pushes nothing on the stack.
436    pub fn lua_getmetatable(state: *mut _LuaState, objindex: c_int) -> c_int;
437
438    /// Pushes onto the stack the environment table of the value at the given index.
439    pub fn lua_getfenv(state: *mut _LuaState, idx: c_int);
440}
441
442extern "C-unwind" {
443    /// Does the equivalent to t\[k\] = v, where t is the value at the given valid index, v is the value at the top of the stack, and k is the value just below the top.
444    ///
445    /// This function pops both the key and the value from the stack. As in Luau, this function may trigger a metamethod for the "newindex" event.
446    pub fn lua_settable(state: *mut _LuaState, idx: c_int);
447
448    /// Does the equivalent to t\[k\] = v, where t is the value at the given valid index and v is the value at the top of the stack.
449    ///
450    /// This function pops the value from the stack. As in Luau, this function may trigger a metamethod for the "newindex" event
451    pub fn lua_setfield(state: *mut _LuaState, idx: c_int, k: *const c_char);
452
453    /// Does the equivalent to t\[k\] = v, where t is the value at the given valid index and v is the value at the top of the stack.
454    ///
455    /// This function pops the value from the stack. This function will not trigger metamethods
456    pub fn lua_rawsetfield(state: *mut _LuaState, idx: c_int, k: *const c_char);
457
458    /// Similar to lua_settable, but does a raw assignment (i.e., without metamethods).
459    pub fn lua_rawset(state: *mut _LuaState, idx: c_int);
460
461    /// Does the equivalent of t[n] = v, where t is the value at the given valid index and v is the value at the top of the stack.
462    ///
463    /// This function pops the value from the stack. The assignment is raw; that is, it does not invoke metamethods.
464    pub fn lua_rawseti(state: *mut _LuaState, idx: c_int, idx: c_int);
465
466    /// Pops a table from the stack and sets it as the new metatable for the value at the given acceptable index.
467    pub fn lua_setmetatable(state: *mut _LuaState, objindex: c_int) -> c_int;
468
469    /// Pops a table from the stack and sets it as the new environment for the value at the given index.
470    /// If the value at the given index is neither a function nor a thread nor a userdata, lua_setfenv returns 0. Otherwise it returns 1.
471    pub fn lua_setfenv(state: *mut _LuaState, idx: c_int) -> c_int;
472}
473
474extern "C-unwind" {
475    /// Loads a luau chunk into a function with a chunkname.
476    ///
477    /// Specifying an env will allow for optimizations to be performed, if you do not want to specify an env pass 0.
478    pub fn luau_load(
479        state: *mut _LuaState,
480        chunkname: *const c_char,
481        data: *const c_char,
482        size: usize,
483        env: c_int,
484    ) -> c_int;
485
486    /// Calls a function.
487    ///
488    /// To call a function you must use the following protocol: first, the function to be called is pushed onto the stack; then, the arguments to the function are pushed in direct order; that is, the first argument is pushed first. Finally you call lua_call; nargs is the number of arguments that you pushed onto the stack. All arguments and the function value are popped from the stack when the function is called. The function results are pushed onto the stack when the function returns. The number of results is adjusted to nresults, unless nresults is LUA_MULTRET. In this case, all results from the function are pushed. Luau takes care that the returned values fit into the stack space. The function results are pushed onto the stack in direct order (the first result is pushed first), so that after the call the last result is on the top of the stack.
489    ///
490    /// Any error inside the called function is propagated upwards with a Luau exception.
491    pub fn lua_call(state: *mut _LuaState, nargs: c_int, nresults: c_int);
492
493    /// Calls a function in protected mode.
494    ///
495    /// Both nargs and nresults have the same meaning as in lua_call. If there are no errors during the call, lua_pcall behaves exactly like lua_call. However, if there is any error, lua_pcall catches it, pushes a single value on the stack (the error message), and returns an error code. Like lua_call, lua_pcall always removes the function and its arguments from the stack.
496    ///
497    /// If errfunc is 0, then the error message returned on the stack is exactly the original error message. Otherwise, errfunc is the stack index of an error handler function. (In the current implementation, this index cannot be a pseudo-index.) In case of runtime errors, this function will be called with the error message and its return value will be the message returned on the stack by lua_pcall.
498    ///
499    /// Typically, the error handler function is used to add more debug information to the error message, such as a stack traceback. Such information cannot be gathered after the return of lua_pcall, since by then the stack has unwound.
500    ///
501    /// The lua_pcall function returns 0 in case of success or one of the following error codes:
502    ///
503    /// LUA_ERRRUN: a runtime error. \
504    /// LUA_ERRMEM: memory allocation error. For such errors, Luau does not call the error handler function. \
505    /// LUA_ERRERR: error while running the error handler function.
506    pub fn lua_pcall(
507        state: *mut _LuaState,
508        nargs: c_int,
509        nresults: c_int,
510        errfunc: c_int,
511    ) -> LuauStatus;
512}
513
514extern "C-unwind" {
515    /// Yields a coroutine.
516    ///
517    /// This function should be called as the return expression of a C function, as follows:
518    ///
519    /// When a C function calls lua_yield in that way, the running coroutine suspends its execution, and the call to lua_resume that started this coroutine returns.
520    /// The parameter nresults is the number of values from the stack that are passed as results to lua_resume.
521    pub fn lua_yield(state: *mut _LuaState, nresults: c_int) -> c_int;
522
523    /// Breaks execution of a coroutine
524    ///
525    /// This function could be called as the return expression of a C function
526    ///
527    /// When a C function calls lua_break in that way, the running coroutine stops its execution, and the call to lua_resume that started this coroutine returns.
528    ///
529    /// Will always return -1
530    pub fn lua_break(state: *mut _LuaState) -> c_int;
531
532    /// Starts and resumes a coroutine in the given thread L.
533    ///
534    /// To start a coroutine, you push the main function plus any arguments onto the empty stack of the thread. then you call lua_resume, with nargs being the number of arguments.
535    /// This call returns when the coroutine suspends or finishes its execution. When it returns, *nresults is updated and the top of the stack contains the *nresults values passed to lua_yield or returned by the body function.
536    /// lua_resume returns LUA_YIELD if the coroutine yields, LUA_OK if the coroutine finishes its execution without errors, or an error code in case of errors.
537    /// In case of errors, the error object is on the top of the stack.
538    ///
539    /// To resume a coroutine, you remove the *nresults yielded values from its stack, push the values to be passed as results from yield, and then call lua_resume.
540    ///
541    /// The parameter from represents the coroutine that is resuming L. If there is no such coroutine, this parameter can be NULL.
542    pub fn lua_resume(state: *mut _LuaState, from: *mut _LuaState, narg: c_int) -> LuauStatus;
543
544    /// Resumes a coroutine in the thread L
545    ///
546    /// This errors the thread
547    ///
548    /// The parameter from represents the coroutine that is resuming L. If there is no such coroutine, this parameter can be NULL.
549    pub fn lua_resumeerror(state: *mut _LuaState, from: *mut _LuaState) -> LuauStatus;
550
551    /// Returns the execution status of the provided luau state
552    pub fn lua_status(state: *mut _LuaState) -> LuauStatus;
553
554    /// Returns true if the given coroutine can yield, and false otherwise.
555    pub fn lua_isyieldable(state: *mut _LuaState) -> c_int;
556
557    /// Returns an associated thread userdata pointer
558    pub fn lua_getthreaddata(state: *mut _LuaState) -> *mut c_void;
559
560    /// Sets a thread userdata pointer
561    pub fn lua_setthreaddata(state: *mut _LuaState, data: *mut c_void);
562
563    /// Returns the status of a coroutine
564    pub fn lua_costatus(state: *mut _LuaState, co: *mut _LuaState) -> CoroutineStatus;
565}
566
567// Garbage collection options
568#[repr(C)]
569#[allow(non_camel_case_types)]
570pub enum GCOperation {
571    /// Stop incremental garbage collection
572    LUA_GCSTOP,
573
574    /// Restart incremental garbage collection
575    LUA_GCRESTART,
576
577    /// run a full GC cycle; not recommended for latency sensitive applications
578    LUA_GCCOLLECT,
579
580    /// return the heap size in KB and the remainder in bytes
581    LUA_GCCOUNT,
582
583    /// return the heap size in KB and the remainder in bits
584    LUA_GCCOUNTB,
585
586    /// return 1 if GC is active (not stopped); note that GC may not be actively collecting even if it's running
587    LUA_GCISRUNNING,
588
589    /// Perform an explicit GC step, with the step size specified in KB.
590    ///
591    /// Garbage collection is handled by 'assists' that perform some amount of GC work matching pace of allocation
592    /// explicit GC steps allow to perform some amount of work at custom points to offset the need for GC assists
593    /// note that GC might also be paused for some duration (until bytes allocated meet the threshold)
594    /// if an explicit step is performed during this pause, it will trigger the start of the next collection cycle
595    LUA_GCSTEP,
596
597    /// tune GC parameters G (goal), S (step multiplier) and step size (usually best left ignored)
598    ///
599    /// garbage collection is incremental and tries to maintain the heap size to balance memory and performance overhead
600    /// this overhead is determined by G (goal) which is the ratio between total heap size and the amount of live data in it
601    /// G is specified in percentages; by default G=200% which means that the heap is allowed to grow to ~2x the size of live data.
602    ///
603    /// collector tries to collect S% of allocated bytes by interrupting the application after step size bytes were allocated.
604    /// when S is too small, collector may not be able to catch up and the effective goal that can be reached will be larger.
605    /// S is specified in percentages; by default S=200% which means that collector will run at ~2x the pace of allocations.
606    ///
607    /// it is recommended to set S in the interval 100 / (G - 100), 100 + 100 / (G - 100)) with a minimum value of 150%; for example:
608    /// - for G=200%, S should be in the interval 150% - 200%
609    /// - for G=150%, S should be in the interval 200% - 300%
610    /// - for G=125%, S should be in the interval 400% - 500%
611    LUA_GCSETGOAL,
612
613    /// Refer to LUA_GCSETGOAL
614    LUA_GCSETSTEPMUL,
615
616    /// Refer to LUA_GCSETGOAL
617    LUA_GCSETSTEPSIZE,
618}
619
620// GC operation
621extern "C-unwind" {
622    /// Performs the GC operation specified by the what parameter
623    pub fn lua_gc(state: *mut _LuaState, what: GCOperation, data: c_int) -> c_int;
624}
625
626// Memory statistics
627extern "C-unwind" {
628    /// Sets the active memory category of the provided state
629    pub fn lua_setmemcat(state: *mut _LuaState, category: c_int);
630
631    /// Gets the total allocation size of the provided category.
632    ///
633    /// Returns the total allocation size of all categories if the category provided is zero
634    pub fn lua_totalbytes(state: *mut _LuaState, category: c_int) -> usize;
635}
636
637// Miscellaneous functions
638extern "C-unwind" {
639    /// Errors the current state
640    ///
641    /// Will not return
642    ///
643    /// Will cause an abort in the absence of a protected call
644    pub fn lua_error(state: *mut _LuaState) -> !;
645
646    /// Pops a key from the stack, and pushes a key-value pair from the table at the given index (the "next" pair after the given key).
647    /// If there are no more elements in the table, then lua_next returns 0 (and pushes nothing).
648    pub fn lua_next(state: *mut _LuaState, idx: c_int) -> c_int;
649
650    /// Performs raw Luau iteration (array portion first, hash portion next) without invoking an iter metamethod
651    pub fn lua_rawiter(state: *mut _LuaState, idx: c_int, iter: c_int) -> c_int;
652
653    /// Concatenates the n values at the top of the stack, pops them, and leaves the result at the top.
654    /// If n is 1, the result is the single value on the stack (that is, the function does nothing); if n is 0, the result is the empty string.
655    ///
656    /// Concatenation is performed following the usual semantics of Luau
657    pub fn lua_concat(state: *mut _LuaState, idx: c_int);
658
659    /// Performs pointer encryption
660    pub fn lua_encodepointer(state: *mut _LuaState, p: usize) -> usize;
661
662    /// Returns the value returned by the clock function in use by Luau
663    pub fn lua_clock() -> c_double;
664
665    /// Sets the tag of a full userdata
666    pub fn lua_setuserdatatag(state: *mut _LuaState, idx: c_int, tag: Tag);
667
668    /// Sets a full userdata tag destructor method
669    ///
670    /// This cannot be reassigned
671    ///
672    /// This destructor will be invoked for any of the tagged userdatas with that tag
673    pub fn lua_setuserdatadtor(state: *mut _LuaState, tag: Tag, dtor: Option<LuaDestructor>);
674
675    /// Gets a full userdata tag destructor method
676    pub fn lua_getuserdatadtor(state: *mut _LuaState, tag: Tag) -> Option<LuaDestructor>;
677
678    /// Sets a full userdata tag metatable
679    ///
680    /// This cannot be reassigned
681    ///
682    /// This metatable can be retrieved lua_getuserdatametatable
683    pub fn lua_setuserdatametatable(state: *mut _LuaState, tag: Tag, idx: c_int);
684
685    /// Get's a full userdata tag metatable
686    pub fn lua_getuserdatametatable(state: *mut _LuaState, tag: Tag);
687
688    /// Sets a lightuserdata tag name
689    ///
690    /// This cannot be reassigned
691    ///
692    /// This name can be retrieved lua_getlightuserdataname
693    pub fn lua_setlightuserdataname(state: *mut _LuaState, tag: Tag, name: *const c_char);
694
695    /// Gets a lightuserdata tag name
696    pub fn lua_getlightuserdataname(state: *mut _LuaState, tag: Tag) -> *const c_char;
697
698    /// Clones a function proto and its upvalues
699    pub fn lua_clonefunction(state: *mut _LuaState, idx: c_int);
700
701    /// Clears a table's while retaining its sizes
702    pub fn lua_cleartable(state: *mut _LuaState, idx: c_int);
703
704    /// Gets an allocation C function and sets the provided pointer to the pointer of the associated data
705    pub fn lua_getallocf(state: *mut _LuaState, ud: *mut *mut c_void) -> LuaAlloc;
706}
707
708//
709// Reference system, can be used to pin objects
710//
711pub const LUA_NOREF: c_int = -1;
712pub const LUA_REFNIL: c_int = 0;
713
714#[repr(transparent)]
715#[derive(Debug, Clone, Copy)]
716/// Index into the Luau registry created by lua_ref
717///
718/// Reference indexes are not regular stack indexes and should be handled through lua_getref
719pub struct RefIndex(pub(crate) c_int);
720
721extern "C-unwind" {
722    /// Creates a Luau reference which is used to "pin" a value in a specified place
723    pub fn lua_ref(state: *mut _LuaState, idx: c_int) -> RefIndex;
724
725    /// Removes a Luau value from its position, specified by the ref index, in the registry
726    pub fn lua_unref(state: *mut _LuaState, r#ref: RefIndex);
727}
728
729/// Pushes the value for which a reference was made by `lua_ref`.
730///
731/// Returns the type of the value pushed
732///
733/// # Safety
734/// You should uphold all safety invariants that apply to lua_rawgeti.
735pub unsafe fn lua_getref(state: *mut _LuaState, ref_index: RefIndex) -> LuauType {
736    lua_rawgeti(state, LUA_REGISTRYINDEX, ref_index.0)
737}
738
739//
740// Debug API
741//
742
743// Maximum size for the description of the source of a function in debug information.
744const LUA_IDSIZE: usize = 256;
745
746/// Type for functions to be called on debug events.
747pub type LuaHook = unsafe extern "C-unwind" fn(state: *mut _LuaState, ar: *mut LuaDebug);
748
749pub type LuaCoverage = unsafe extern "C-unwind" fn(
750    context: *mut c_void,
751    function: *const c_char,
752    linedefined: c_int,
753    depth: c_int,
754    hits: *const c_int,
755    size: usize,
756);
757
758#[repr(C)]
759pub struct LuaDebug {
760    /// Field 'n'
761    ///
762    /// Name of the current function
763    pub name: *const c_char, // (n)
764    /// Set by field 's'
765    ///
766    /// Returns the "kind" of execution
767    ///
768    /// Values are:
769    /// "Luau",
770    /// "C",
771    /// "main",
772    /// "tail"
773    pub what: *const c_char,
774
775    /// Set by field 's'
776    ///
777    /// The source (chunkname) of an error.
778    ///
779    /// Tf the error is from a C function will be set to '=[C]'
780    pub source: *const c_char,
781
782    /// Set by field 's'
783    ///
784    /// Truncated form of the chunkname with some additional formatting rules not exceeding LUA_IDSIZE in length
785    pub short_src: *const c_char,
786
787    /// Set by field 's'
788    ///
789    /// The line on which the function was defined
790    pub linedefined: c_int,
791
792    /// Set by field 'l'
793    ///
794    /// Returns the current line in execution
795    pub currentline: c_int,
796
797    /// Set by field 'u'
798    ///
799    /// The number of upvalues for the function
800    pub nupvals: c_uchar,
801
802    /// Set by field 'a'
803    ///
804    /// The number of params accepted by the function
805    pub nparams: c_uchar,
806
807    /// Set by field 'a'
808    ///
809    /// 1 if the function is a vararg function
810    ///
811    /// 0 if it is not
812    pub isvararg: c_char,
813
814    /// Userdata field for lua_Debug
815    ///
816    /// Is only valid for luau_callhook
817    pub userdata: *mut c_void, // only valid in luau_callhook
818
819    /// Buffer used for short_src operation
820    pub ssbuf: [c_char; LUA_IDSIZE],
821}
822
823extern "C-unwind" {
824    /// Returns the state's current call stack depth
825    pub fn lua_stackdepth(state: *mut _LuaState) -> c_int;
826
827    /// Fills a LuaDebug structure with information specified by the `what` argument and pushes the function to the top of the stack.
828    ///
829    /// Level is expected to be a stack index (negative) or a callstack depth (positive)
830    pub fn lua_getinfo(
831        state: *mut _LuaState,
832        level: c_int,
833        what: *const c_char,
834        ar: *mut LuaDebug,
835    ) -> c_int;
836
837    /// Returns the argument "n" passed at call level "level"
838    pub fn lua_getargument(state: *mut _LuaState, level: c_int, idx: c_int) -> c_int;
839
840    /// Gets the local `n` at call level `level` and pushes it to the top of the stack
841    ///
842    /// Returns the name of the local or NULL if it does not exist
843    pub fn lua_getlocal(state: *mut _LuaState, level: c_int, idx: c_int) -> *const c_char;
844
845    /// Sets the local `n` at call level `level` to a value popped from the top of the stack
846    ///
847    /// Returns the name of the local or NULL if it does not exist
848    ///
849    /// Note: This cannot be used for functions compiled with native codegen
850    pub fn lua_setlocal(state: *mut _LuaState, level: c_int, idx: c_int) -> *const c_char;
851
852    /// Gets upvalue `n` from function at `funcindex` and pushes it to the top of the stack
853    ///
854    /// Returns the name of the upvalue or NULL if the upvalue doesnt exist
855    pub fn lua_getupvalue(state: *mut _LuaState, funcindex: c_int, idx: c_int) -> *const c_char;
856
857    /// Retrieves and sets the upvalue `n` for function at `funcindex` to a value popped from the top of the stack
858    ///
859    /// Returns the name of the upvalue or NULL if the upvalue doesnt exist
860    pub fn lua_setupvalue(state: *mut _LuaState, funcindex: c_int, idx: c_int) -> *const c_char;
861
862    /// Sets single-step mode to be enabled or disabled, this allows for a callback to be invoked on every instruction and stops execution of native compiled code.
863    pub fn lua_singlestep(state: *mut _LuaState, enabled: c_int);
864
865    /// Sets a breakpoint status at the specified line and func index
866    ///
867    /// Will return the actual line that the breakpoint was placed on or -1 if it was unsuccessful
868    pub fn lua_breakpoint(
869        state: *mut _LuaState,
870        funcindex: c_int,
871        line: c_int,
872        enabled: c_int,
873    ) -> c_int;
874
875    /// Invokes the LuaCoverage for every proto which contains coverage information
876    ///
877    /// Accepts a user provided context pointer
878    pub fn lua_getcoverage(
879        state: *mut _LuaState,
880        funcindex: c_int,
881        context: *mut c_void,
882        callback: LuaCoverage,
883    );
884
885    /// Outputs a Luau stack trace with a maximum length of 4096
886    ///
887    /// The returned pointer is to a shared buffer used by all calls to this function so the returned value should be copied if it is to be retained past the break scope
888    pub fn lua_debugtrace(state: *mut _LuaState) -> *const c_char;
889}
890
891#[repr(C)]
892#[non_exhaustive]
893/// Callbacks that can be used to reconfigure behavior of the VM dynamically.
894///
895/// These are shared between all coroutines.
896pub struct LuaCallbacks {
897    /// arbitrary userdata pointer that is never overwritten by Luau
898    pub userdata: *mut c_void,
899
900    /// gets called at safepoints (loop back edges, call/ret, gc) if set
901    pub interrupt: Option<unsafe extern "C-unwind" fn(state: *mut _LuaState, gc: c_int)>,
902
903    /// gets called when an unprotected error is raised (if longjmp is used)
904    pub panic: Option<unsafe extern "C-unwind" fn(state: *mut _LuaState, errcode: LuauStatus)>,
905
906    /// gets called when L is created (LP == parent) or destroyed (LP == NULL)
907    pub userthread: Option<unsafe extern "C-unwind" fn(LP: *mut _LuaState, state: *mut _LuaState)>,
908
909    /// gets called when a string is created; returned atom can be retrieved via tostringatom
910    pub useratom: Option<unsafe extern "C-unwind" fn(s: *const c_char, l: usize) -> i16>,
911
912    /// gets called when BREAK instruction is encountered
913    pub debugbreak: Option<unsafe extern "C-unwind" fn(state: *mut _LuaState, ar: *mut LuaDebug)>,
914
915    /// gets called after each instruction in single step mode
916    pub debugstep: Option<unsafe extern "C-unwind" fn(state: *mut _LuaState, ar: *mut LuaDebug)>,
917
918    /// gets called when thread execution is interrupted by break in another thread
919    pub debuginterrupt:
920        Option<unsafe extern "C-unwind" fn(state: *mut _LuaState, ar: *mut LuaDebug)>,
921
922    /// gets called when protected call results in an error
923    pub debugprotectederror: Option<unsafe extern "C-unwind" fn(state: *mut _LuaState)>,
924
925    /// gets called when memory is allocated
926    pub onallocate:
927        Option<unsafe extern "C-unwind" fn(state: *mut _LuaState, osize: usize, nsize: usize)>,
928}
929
930extern "C" {
931    /// Returns a pointer to the Luau callbacks struct
932    pub fn lua_callbacks(state: *mut _LuaState) -> *mut LuaCallbacks;
933}
934
935/// Converts the Luau value at the given index to a Luau number. The Luau value must be a number or a string convertible to a number, otherwise returns 0.
936pub unsafe fn lua_tonumber(state: *mut _LuaState, idx: c_int) -> LuaNumber {
937    lua_tonumberx(state, idx, null_mut())
938}
939
940/// Converts the Luau value at the given index to the signed integral type. The Luau value must be an integer, or a number or string convertible to an integer; otherwise, returns 0.
941pub unsafe fn lua_tointeger(state: *mut _LuaState, idx: c_int) -> LuaInteger {
942    lua_tointegerx(state, idx, null_mut())
943}
944
945/// Converts the Luau value at the given index to the unsigned integral type. The Luau value must be an integer, or a number or string convertible to an integer; otherwise, returns 0.
946pub unsafe fn lua_tounsigned(state: *mut _LuaState, idx: c_int) -> LuaUnsigned {
947    lua_tounsignedx(state, idx, null_mut())
948}
949
950/// Pops n elements from the stack.
951pub unsafe fn lua_pop(state: *mut _LuaState, idx: c_int) {
952    lua_settop(state, -(idx) - 1);
953}
954
955pub unsafe fn lua_newtable(state: *mut _LuaState) {
956    lua_createtable(state, 0, 0)
957}
958pub unsafe fn lua_newuserdata(state: *mut _LuaState, s: usize) -> *mut c_void {
959    lua_newuserdatatagged(state, s, Tag(0))
960}
961
962pub unsafe fn lua_strlen(state: *mut _LuaState, i: c_int) -> c_int {
963    lua_objlen(state, i)
964}
965
966/// Returns true if the value at `idx` is a function, false otherwise.
967pub unsafe fn lua_isfunction(state: *mut _LuaState, idx: c_int) -> bool {
968    lua_type(state, idx) == LuauType::LUA_TFUNCTION
969}
970
971/// Returns true if the value at `idx` is a table, false otherwise.
972pub unsafe fn lua_istable(state: *mut _LuaState, idx: c_int) -> bool {
973    lua_type(state, idx) == LuauType::LUA_TTABLE
974}
975
976/// Returns true if the value at `idx` is a light userdata, false otherwise.
977pub unsafe fn lua_islightuserdata(state: *mut _LuaState, idx: c_int) -> bool {
978    lua_type(state, idx) == LuauType::LUA_TLIGHTUSERDATA
979}
980
981/// Returns true if the value at `idx` is nil, false otherwise.
982pub unsafe fn lua_isnil(state: *mut _LuaState, idx: c_int) -> bool {
983    lua_type(state, idx) == LuauType::LUA_TNIL
984}
985
986/// Returns true if the value at `idx` is a boolean, false otherwise.
987pub unsafe fn lua_isboolean(state: *mut _LuaState, idx: c_int) -> bool {
988    lua_type(state, idx) == LuauType::LUA_TBOOLEAN
989}
990
991/// Returns true if the value at `idx` is a vector, false otherwise.
992pub unsafe fn lua_isvector(state: *mut _LuaState, idx: c_int) -> bool {
993    lua_type(state, idx) == LuauType::LUA_TVECTOR
994}
995
996/// Returns true if the value at `idx` is a thread, false otherwise.
997pub unsafe fn lua_isthread(state: *mut _LuaState, idx: c_int) -> bool {
998    lua_type(state, idx) == LuauType::LUA_TTHREAD
999}
1000
1001/// Returns true if the value at `idx` is a buffer, false otherwise.
1002pub unsafe fn lua_isbuffer(state: *mut _LuaState, idx: c_int) -> bool {
1003    lua_type(state, idx) == LuauType::LUA_TBUFFER
1004}
1005
1006/// Returns true if the value at `n` doesn't exist, false otherwise.
1007pub unsafe fn lua_isnone(state: *mut _LuaState, idx: c_int) -> bool {
1008    lua_type(state, idx) == LuauType::LUA_TNONE
1009}
1010
1011/// Returns true if the value at `n` doesnt exist or is nil
1012pub unsafe fn lua_isnoneornil(state: *mut _LuaState, idx: c_int) -> bool {
1013    lua_type(state, idx) <= LuauType::LUA_TNIL
1014}
1015
1016/// Pushes a static string to Luau
1017pub unsafe fn lua_pushliteral(state: *mut _LuaState, s: &'static str) {
1018    lua_pushlstring(state, s.as_ptr() as _, s.len())
1019}
1020
1021/// Pushes a C function with no upvalues and the given debug name
1022pub unsafe fn lua_pushcfunction(state: *mut _LuaState, func: CFunction, debugname: *const c_char) {
1023    lua_pushcclosurek(state, func, debugname, 0, None);
1024}
1025
1026/// Pushes a C function with the given amount of upvalues
1027pub unsafe fn lua_pushcclosure(
1028    state: *mut _LuaState,
1029    func: CFunction,
1030    debugname: *const c_char,
1031    nup: c_int,
1032) {
1033    lua_pushcclosurek(state, func, debugname, nup, None)
1034}
1035
1036pub unsafe fn lua_pushlightuserdata(state: *mut _LuaState, p: *mut c_void) {
1037    lua_pushlightuserdatatagged(state, p, Tag(0))
1038}
1039
1040/// Pops a value from the stack and sets it as the new value of global name.
1041pub unsafe fn lua_setglobal(state: *mut _LuaState, s: *const c_char) {
1042    lua_setfield(state, LUA_GLOBALSINDEX, s)
1043}
1044
1045/// Pushes onto the stack the value of the global name. Returns the type of that value.
1046pub unsafe fn lua_getglobal(state: *mut _LuaState, s: *const c_char) -> LuauType {
1047    lua_getfield(state, LUA_GLOBALSINDEX, s)
1048}
1049
1050pub unsafe fn lua_tostring(state: *mut _LuaState, i: c_int) -> *const c_char {
1051    lua_tolstring(state, i, null_mut())
1052}
1053
1054#[macro_export]
1055macro_rules! lua_pushformat {
1056    ($state:expr, $fmt:expr, $($args:tt)*) => {
1057        let string = std::fmt::format(format_args!($fmt, $($args)*));
1058        $crate::ffi::prelude::lua_pushlstring($state, string.as_str().as_ptr() as _, string.len())
1059    };
1060}