lunka/thread.rs
1//! See [`Thread`].
2
3use crate::{
4 Coroutine,
5 GcMode,
6 cdef::*,
7 managed::*
8};
9
10#[cfg(feature = "auxlib")]
11use crate::{
12 aux_options::*,
13 cdef::auxlib::*,
14 reg::*,
15};
16
17use core::{
18 ffi::{
19 c_char, c_int, c_uint, c_void, CStr,
20 },
21 marker::PhantomData,
22 mem::transmute,
23 ptr::{
24 null, null_mut, NonNull
25 },
26 slice::from_raw_parts,
27};
28
29macro_rules! lua_is {
30 (
31 @bool
32 $(#[$attr:meta])*
33 $vis:vis fn $name:ident(&self, index: c_int) -> bool
34 for $ffi_fn:ident
35 ) => {
36 $(#[$attr])*
37 $vis fn $name(&self, index: c_int) -> bool {
38 unsafe { $ffi_fn(self.as_ptr(), index) }
39 }
40 };
41
42 (
43 @c_int
44 $(#[$attr:meta])*
45 $vis:vis fn $name:ident(&self, index: c_int) -> bool
46 for $ffi_fn:ident
47 ) => {
48 $(#[$attr])*
49 $vis fn $name(&self, index: c_int) -> bool {
50 (unsafe { $ffi_fn(self.as_ptr(), index) }) != 0
51 }
52 };
53
54 (
55 $(
56 $(#[$attr:meta])*
57 $vis:vis fn $name:ident(&self, index: c_int) -> bool
58 for $ffi_fn:ident -> $ffi_fn_ret:tt;
59 )*
60 ) => {
61 $(
62 lua_is!{
63 @ $ffi_fn_ret
64 $(#[$attr])*
65 $vis fn $name(&self, index: c_int) -> bool
66 for $ffi_fn
67 }
68 )*
69 };
70}
71
72/// Opaque type that represents a Lua thread, which is used by
73/// [`Lua`](crate::Lua) and other structures.
74///
75/// This type can never have an instance made of it; there can only be
76/// references to this type, which are the only kind of valid value.
77///
78/// # Borrowing
79/// Most methods use `&mut Thread` as `&Thread`, even though, at least
80/// *in theory*, they should've borrowed mutably with `&mut Thread`.
81/// For instance, [`Thread::push_nil`], even though it modifies the Lua stack by
82/// pushing a `nil`, still borrows a [`Thread`] immutably.
83///
84/// In the case for this structure, borrowing immutably means **not in any way
85/// being able to trigger the GC to collect garbage**.
86/// Any references returned by methods for this structure are simply the same
87/// pointers that the C API returns, though they are converted to references for
88/// the Rust borrow checker to ensure safety.
89/// The Lua garbage collector will not invalidate any pointers if it is stopped.
90///
91/// To call API functions that can potentially enable the GC, it is required
92/// that any references that have been acquired previously from a [`Thread`] are
93/// immediately invalidated, so they cannot be used *if* the garbage collector
94/// decides to collect them.
95/// This is done by borrowing [`Thread`] mutably once, through
96/// [`Thread::run_managed`], which allows for more operations.
97///
98/// The main reason for this model existing is because it may be difficult to
99/// formally prove that a reference would not be collected without using stack
100/// indices. This model simply utilizes checks done at compile time to ensure
101/// safety.
102#[derive(Debug)]
103#[repr(transparent)]
104pub struct Thread {
105 _no_new: (),
106}
107
108impl Thread {
109 /// Construct a reference to [`Thread`] from a raw C pointer to a Lua state.
110 ///
111 /// # Safety
112 /// `l` must point to a valid Lua state (`lua_State *` in C), for the
113 /// duration specified by `'a`.
114 pub unsafe fn from_ptr<'a>(l: *mut State) -> &'a Self {
115 unsafe { &*(l as *mut Self) }
116 }
117
118 /// Construct a _mutable_ reference to [`Thread`] from a raw C pointer to a
119 /// Lua state.
120 ///
121 /// # Safety
122 /// `l` must point to a valid Lua state (`lua_State *` in C), for the
123 /// duration specified by `'a`.
124 ///
125 /// **You must also, however, abide by Rust's aliasing rules.**
126 /// This means that you must guarantee that there
127 /// may not be two `&mut Thread`s that point to the same state,
128 /// nor a `&Thread` and a `&mut Thread`.
129 pub unsafe fn from_ptr_mut<'a>(l: *mut State) -> &'a mut Self {
130 unsafe { &mut *(l as *mut Self) }
131 }
132
133 /// Return the raw C pointer that represents the underlying Lua state.
134 pub fn as_ptr(&self) -> *mut State {
135 self as *const Self as *mut State
136 }
137
138 /// Run code that can restart the GC and potentially invalidate pointers
139 /// in a context.
140 pub fn run_managed<R>(&mut self, func: impl FnOnce(Managed<'_>) -> R) -> R {
141 func(Managed {
142 l: self.as_ptr(),
143 _life: PhantomData
144 })
145 }
146
147 /// This is the same as [`Thread::run_managed`], however it doesn't borrow
148 /// mutably by assuming that the garbage collector will not collect (and
149 /// thus invalidate) any outside references.
150 ///
151 /// # Safety
152 /// The body of `func` must not include any operations that may cause the
153 /// garbage collector to run a cycle.
154 ///
155 /// For example, if performing arithmetic on numbers does not trigger any
156 /// metamethods, or it triggers metamethods that can't ever cause the
157 /// collector to collect, then this invariant is not broken.
158 pub unsafe fn run_managed_no_gc<R>(
159 &self,
160 func: impl FnOnce(Managed<'_>) -> R
161 ) -> R {
162 func(Managed {
163 l: self.as_ptr(),
164 _life: PhantomData
165 })
166 }
167
168 /// Close all active to-be-closed variables in the main thread, release all
169 /// objects (calling the corresponding garbage-collection metamethods, if
170 /// any), and free all dynamic memory used by this [`Thread`].
171 ///
172 /// # Safety
173 /// This [`Thread`] must not be used for any further API calls, as the
174 /// underlying Lua pointer becomes invalid after this call.
175 pub unsafe fn close_as_main(&mut self) {
176 unsafe { lua_close(self.as_ptr()) }
177 }
178
179 /// Reset a thread, cleaning its call stack and closing all pending
180 /// to-be-closed variables.
181 ///
182 /// Returns a status code: [`Status::Ok`] for no errors in the thread
183 /// (either the original error that stopped the thread or errors in closing
184 /// methods), or an error status otherwise.
185 ///
186 /// In case of error, leaves the error object on the top of its own stack.
187 pub fn close_as_coroutine(&mut self) -> Status {
188 unsafe { Status::from_c_int_unchecked(lua_resetthread(self.as_ptr())) }
189 }
190
191 /// This behaves similarly to [`Thread::close_as_coroutine`], but allows to specify `from`,
192 /// which represents the coroutine that is resetting this one.
193 pub fn close_as_coroutine_from(&mut self, from: &Self) -> Status {
194 unsafe { Status::from_c_int_unchecked(
195 lua_closethread(self.as_ptr(), from.as_ptr())
196 ) }
197 }
198
199 /// Set a new panic function and return the old one.
200 pub fn at_panic(&self, func: Option<CFunction>) -> Option<CFunction> {
201 unsafe { lua_atpanic(self.as_ptr(), func) }
202 }
203
204 /// Raise a Lua error, using the value on the top of the stack as the error
205 /// object.
206 ///
207 /// This function does a long jump, and therefore never returns.
208 pub fn error(&self) -> ! {
209 unsafe { lua_error(self.as_ptr()) }
210 }
211
212 /// Restart the garbage collector.
213 ///
214 /// This by itself does not run a collection.
215 pub fn restart_gc(&self) {
216 unsafe { lua_gc(self.as_ptr(), GcTask::Restart as _) };
217 }
218
219 /// Stop the garbage collector.
220 pub fn stop_gc(&self) {
221 unsafe { lua_gc(self.as_ptr(), GcTask::Stop as _) };
222 }
223
224 /// Return the current amount of memory (in kilobytes) in use by this [`Thread`].
225 pub fn mem_kbytes(&self) -> c_uint {
226 unsafe { lua_gc(self.as_ptr(), GcTask::CountKbytes as _) }
227 .clamp(0, c_int::MAX) as _
228 }
229
230 /// Return the remainder of dividing the current amount of bytes of memory in use by this [`Thread`] by `1024`.
231 pub fn mem_byte_remainder(&self) -> c_uint {
232 unsafe { lua_gc(self.as_ptr(), GcTask::CountBytesRem as _) }
233 .clamp(0, c_int::MAX) as _
234 }
235
236 /// Return true if the collector is running (i.e. not stopped).
237 pub fn is_gc_running(&self) -> bool {
238 (unsafe { lua_gc(self.as_ptr(), GcTask::IsRunning as _) }) != 0
239 }
240
241 /// Change the collector to either incremental or generational mode (see also [`GcMode`]) with the given parameters.
242 pub fn switch_gc_to(&mut self, gc: GcMode) {
243 match gc {
244 GcMode::Incremental { pause, step_multiplier, step_size } => unsafe {
245 lua_gc(
246 self.as_ptr(), GcTask::ToIncremental as _,
247 pause as c_int, step_multiplier as c_int, step_size
248 )
249 },
250 GcMode::Generational { minor_mul, major_mul } => unsafe {
251 lua_gc(
252 self.as_ptr(), GcTask::ToGenerational as _,
253 minor_mul as c_int, major_mul as c_int
254 )
255 }
256 };
257 }
258
259 /// Convert the acceptable index `idx` into an equivalent absolute index
260 /// (that is, one that does not depend on the stack size).
261 pub fn abs_index(&self, idx: c_int) -> c_int {
262 unsafe { lua_absindex(self.as_ptr(), idx) }
263 }
264
265 /// Ensure that the stack has space for at least `n` extra elements.
266 /// That is, that you can safely push up to `n` values into it.
267 ///
268 /// Returns `false` if it cannot fulfill the request, either because it
269 /// would cause the stack to be greater than a fixed maximum size (typically
270 /// at least several thousand elements) or because it cannot allocate memory
271 /// for the extra space.
272 ///
273 /// This function never shrinks the stack; if the stack already has space
274 /// for the extra elements, it is left unchanged.
275 pub fn test_stack(&self, n: c_uint) -> bool {
276 (unsafe { lua_checkstack(self.as_ptr(), n as _) }) != 0
277 }
278
279 /// Copy the element at `from_idx` into the valid index `to_idx`, replacing
280 /// the value at that position.
281 ///
282 /// Values at other positions are not affected.
283 pub fn copy(&self, from_idx: c_int, to_idx: c_int) {
284 unsafe { lua_copy(self.as_ptr(), from_idx, to_idx) }
285 }
286
287 /// Create a new empty table and push it onto the stack.
288 ///
289 /// `narr` is a hint for how many elements the table will have as a sequence,
290 /// and `nrec` is a hint for how many other elements the table will have.
291 /// Lua may use these hints to preallocate memory for the new table.
292 /// This preallocation may help performance when its known in advance how
293 /// many elements the table will have.
294 ///
295 /// See also [`Thread::new_table`].
296 ///
297 /// # Errors
298 /// The underlying Lua state may raise a memory [error](crate::errors).
299 pub fn create_table(&self, n_arr: c_uint, n_rec: c_uint) {
300 unsafe { lua_createtable(self.as_ptr(), n_arr as _, n_rec as _) }
301 }
302
303 /// Dump a function as a binary chunk, and return the status of the
304 /// operation.
305 ///
306 /// This function receives a Lua function on the top of the stack and
307 /// produces a binary chunk that, if loaded again, results in a function
308 /// equivalent to the one dumped.
309 ///
310 /// As it produces parts of the chunk, the function calls `writer` (see also
311 /// [`Writer`]) with the given data to write them.
312 /// If `strip_debug_info` is `true`, the binary representation may not
313 /// include all debug information about the function, to save space.
314 ///
315 /// The value returned is the error code returned by the last call to the
316 /// writer.
317 ///
318 /// This function does not pop the Lua function from the stack.
319 ///
320 /// # Safety
321 /// `writer_data` must be valid to be passed to `writer`.
322 pub unsafe fn dump(
323 &self,
324 writer: Writer, writer_data: *mut c_void,
325 strip_debug_info: bool
326 ) -> c_int {
327 unsafe { lua_dump(
328 self.as_ptr(),
329 writer, writer_data,
330 if strip_debug_info { 1 } else { 0 }
331 ) }
332 }
333
334 /// Return the memory-allocation function of this [`Thread`] along with the
335 /// opaque pointer given when the memory-allocator function was set.
336 pub fn get_alloc_fn(&self) -> (Alloc, *mut c_void) {
337 let mut ud = null_mut();
338 let alloc_fn = unsafe { lua_getallocf(
339 self.as_ptr(), &mut ud as *mut *mut c_void
340 ) };
341 (alloc_fn, ud)
342 }
343
344 /// Push onto the stack the value of the global `name`, and return the type
345 /// of that value.
346 ///
347 /// # Errors
348 /// The underlying Lua state may raise an arbitrary [error](crate::errors).
349 pub fn get_global(&self, name: &CStr) -> Type {
350 unsafe { Type::from_c_int_unchecked(lua_getglobal(self.as_ptr(), name.as_ptr())) }
351 }
352
353 /// Push onto the stack the `n`-th user value associated with the full
354 /// userdata at the given index and returns the type of the pushed value.
355 ///
356 /// If the userdata does not have that value, push `nil` and return [`Type::None`].
357 pub fn get_i_uservalue(&self, ud_index: c_int, n: c_int) -> Type {
358 unsafe { Type::from_c_int_unchecked(
359 lua_getiuservalue(self.as_ptr(), ud_index, n)
360 ) }
361 }
362
363 /// If the value at the given index has a metatable, push that metatable
364 /// onto the stack and return `true`. Otherwise, push nothing and return
365 /// `false`.
366 pub fn get_metatable(&self, obj_index: c_int) -> bool {
367 (unsafe { lua_getmetatable(self.as_ptr(), obj_index) }) != 0
368 }
369
370 /// Return the index of the top element in the stack.
371 ///
372 /// Because indices start at `1`, this result is equal to the number of
373 /// elements in the stack; in particular, `0` means an empty stack.
374 pub fn top(&self) -> c_int {
375 unsafe { lua_gettop(self.as_ptr()) }
376 }
377
378 /// Move the top element into the given valid index, shifting up the
379 /// elements above that index to open space.
380 ///
381 /// This function cannot be called with a pseudo-index, because a
382 /// pseudo-index is not an actual stack position.
383 pub fn insert(&self, index: c_int) {
384 unsafe { lua_insert(self.as_ptr(), index) }
385 }
386
387 lua_is! {
388 /// Return `true` if the value at the given index is a boolean.
389 pub fn is_boolean(&self, index: c_int) -> bool for lua_isboolean -> bool;
390
391 /// Return `true` if the value at the given index is a C function.
392 pub fn is_c_function(&self, index: c_int) -> bool
393 for lua_iscfunction -> c_int;
394
395 /// Return `true` if the value at the given index is a function (either
396 /// C or Lua).
397 pub fn is_function(&self, index: c_int) -> bool
398 for lua_isfunction -> bool;
399
400 /// Return `true` if the value at the given index is an integer.
401 pub fn is_integer(&self, index: c_int) -> bool
402 for lua_isinteger -> c_int;
403
404 /// Return `true` if the value at the given index is a light userdata.
405 pub fn is_light_userdata(&self, index: c_int) -> bool
406 for lua_islightuserdata -> bool;
407
408 /// Return `true` if the value at the given index is `nil`.
409 pub fn is_nil(&self, index: c_int) -> bool for lua_isnil -> bool;
410
411 /// Return `true` if the value at the given index is not valid.
412 pub fn is_none(&self, index: c_int) -> bool for lua_isnone -> bool;
413
414 /// Return `true` if the value at the given index is not valid or is
415 /// `nil`.
416 pub fn is_none_or_nil(&self, index: c_int) -> bool
417 for lua_isnoneornil -> bool;
418 /// Return `true` if the value at the given index is a number.
419
420 pub fn is_number(&self, index: c_int) -> bool for lua_isnumber -> c_int;
421
422 /// Return `true` if the value at the given index is a string *or* a
423 /// number, which is always convertible to a string.
424 pub fn is_string(&self, index: c_int) -> bool for lua_isstring -> c_int;
425
426 /// Return `true` if the value at the given index is a table.
427 pub fn is_table(&self, index: c_int) -> bool for lua_istable -> bool;
428
429 /// Return `true` if the value at the given index is a thread.
430 pub fn is_thread(&self, index: c_int) -> bool for lua_isthread -> bool;
431
432 /// Return `true` if the value at the given index is a userdata (either
433 /// full or light).
434 pub fn is_userdata(&self, index: c_int) -> bool
435 for lua_isuserdata -> c_int;
436 }
437
438 /// Return `true` if the coroutine can yield.
439 pub fn can_yield(&self) -> bool {
440 (unsafe { lua_isyieldable(self.as_ptr()) }) != 0
441 }
442
443 /// Load a Lua chunk without running it.
444 ///
445 /// If there are no errors, push the compiled chunk as a Lua function.
446 /// Otherwise, push an error message.
447 ///
448 /// This function uses a user-supplied `reader` to read the chunk (see also
449 /// [`Reader`]).
450 /// `reader_data` is an opaque value passed to the reader function.
451 ///
452 /// `chunk_name` gives a name to the chunk, which is used for error messages
453 /// and in debug information.
454 ///
455 /// The function automatically detects whether the chunk is text or binary
456 /// and loads it accordingly.
457 /// The string `mode` works similarly as in the Lua base library function
458 /// `load`:
459 /// - `Some("b")` loads only binary chunks.
460 /// - `Some("t")` loads only text chunks.
461 /// - `Some("bt")` loads both binary and text chunks.
462 /// - `None` is equivalent to the string `"bt"`.
463 ///
464 /// This function uses the stack internally, so `reader` must always leave
465 /// the stack *unmodified* when returning.
466 ///
467 /// If the resulting function has upvalues, its first upvalue is set to the
468 /// value of the global environment stored at index [`REGISTRY_GLOBALS`] in
469 /// the registry.
470 /// When loading main chunks, this upvalue will be the `_ENV` variable.
471 /// Other upvalues are initialized with `nil`.
472 ///
473 /// # Safety
474 /// `reader_data` must be valid to be passed to `reader`.
475 pub unsafe fn load(
476 &self,
477 reader: Reader, reader_data: *mut c_void,
478 chunk_name: &CStr, mode: Option<&CStr>
479 ) -> Status {
480 unsafe { Status::from_c_int_unchecked(
481 lua_load(
482 self.as_ptr(),
483 reader, reader_data,
484 chunk_name.as_ptr(),
485 mode.map(|cstr| cstr.as_ptr()).unwrap_or(null())
486 )
487 ) }
488 }
489
490 /// Create a new empty table and push it onto the stack.
491 ///
492 /// See also [`Thread::create_table`].
493 ///
494 /// # Errors
495 /// The underlying Lua state may raise a memory [error](crate::errors).
496 pub fn new_table(&self) {
497 unsafe { lua_newtable(self.as_ptr()) }
498 }
499
500 /// Create a new thread, push it on the stack, and return a [`Coroutine`]
501 /// that represents this new thread.
502 ///
503 /// The new thread returned by this function shares with the original thread
504 /// its global environment, but has an independent execution stack.
505 /// Threads are subject to garbage collection, like any Lua object.
506 ///
507 /// # Errors
508 /// The underlying Lua state may raise a memory [error](crate::errors).
509 pub fn new_thread(&self) -> Coroutine<'_> {
510 Coroutine::new(unsafe { Thread::from_ptr_mut(lua_newthread(self.as_ptr())) })
511 }
512
513 /// Create and push on the stack a new full userdata, with `n_uservalues`
514 /// associated Lua values, called user values, and an associated block of
515 /// raw memory of `size` bytes.
516 ///
517 /// The function returns a pointer to the block of memory that was allocated
518 /// by Lua.
519 ///
520 /// The user values can be set and read with the functions
521 /// [`Thread::set_i_uservalue`] and [`Thread::get_i_uservalue`].
522 ///
523 /// You may use this function if, for instance, the layout of the data in
524 /// the allocation changes based on run-time information.
525 ///
526 /// # Errors
527 /// The underlying Lua state may raise a memory [error](crate::errors).
528 ///
529 /// # Safety
530 /// Lua ensures that the pointer is valid as long as the corresponding userdata is alive.
531 /// Moreover, if the userdata is marked for finalization,
532 /// it is valid at least until the call to its finalizer.
533 /// The returned pointer must only be used while it's valid.
534 ///
535 /// Lua makes no guarantees about the alignment of the pointer.
536 /// It depends entirely on the allocator function used.
537 pub unsafe fn new_userdata_raw(
538 &self,
539 size: usize,
540 n_uservalues: c_int,
541 ) -> *mut c_void {
542 unsafe { lua_newuserdatauv(self.as_ptr(), size, n_uservalues) }
543 }
544
545 /// Pop a key from the stack, and push a key–value pair from the table at
546 /// the given index, the "next" pair after the given key.
547 ///
548 /// This function returns `true` while there are still elements to go
549 /// through. If there are no more elements in the table, then this it
550 /// returns `false` and pushes nothing.
551 ///
552 /// # Note on string conversion functions
553 /// While traversing a table, avoid calling [`Thread::to_c_chars`] directly
554 /// on a key, unless it is known that the key is actually a **string**.
555 /// [`Thread::to_c_chars`] and other similar functions may change the value
556 /// at the given index; this confuses the next call to [`Thread::next`].
557 ///
558 /// # Errors
559 /// The underlying Lua state may raise an [error](crate::errors)
560 /// if a given key is neither `nil` nor present in the table.
561 pub fn next(&self, index: c_int) -> bool {
562 (unsafe { lua_next(self.as_ptr(), index) }) != 0
563 }
564
565 /// Push a [`bool`] onto the stack.
566 pub fn push_boolean(&self, value: bool) {
567 unsafe { lua_pushboolean(self.as_ptr(), if value { 1 } else { 0 }) }
568 }
569
570 /// Push a new C closure onto the stack.
571 ///
572 /// This function receives a C function `func` and pushes onto the stack a
573 /// Lua value of type `function` that, when called, invokes the
574 /// corresponding C function.
575 /// `n_upvalues` tells how many upvalues this function will have.
576 ///
577 /// Any function to be callable by Lua must follow the correct protocol to
578 /// receive its parameters and return its results (see [`CFunction`]).
579 ///
580 /// # C closures
581 /// When a C function is created, it is possible to associate some values
582 /// with it, which are called *upvalues*.
583 /// These upvalues are then accessible to the function whenever it is called,
584 /// where the function is called a *C closure*. To create a C closure:
585 /// 1. Push the initial values for its upvalues onto the stack.
586 /// (When there are multiple upvalues, the first value is pushed first.)
587 /// 2. Call this function with the argument `n_upvalues`
588 /// telling how many upvalues will be associated with the function.
589 /// The function will also pop these values from the stack.
590 ///
591 /// When `n_upvalues == 0`, this function creates a "light" C function,
592 /// which is just a pointer to the C function. In that case, it never raises
593 /// a memory error.
594 ///
595 /// See also [`Thread::push_c_function`].
596 ///
597 /// # Errors
598 /// The underlying Lua state may raise a memory [error](crate::errors) if `n_upvalues > 0`.
599 pub fn push_c_closure(&self, func: CFunction, n_upvalues: c_int) {
600 unsafe { lua_pushcclosure(self.as_ptr(), func, n_upvalues) }
601 }
602
603 /// Push a light C function onto the stack (that is, a C function with no
604 /// upvalues).
605 ///
606 /// See also [`Thread::push_c_closure`].
607 pub fn push_c_function(&self, func: CFunction) {
608 unsafe { lua_pushcfunction(self.as_ptr(), func) }
609 }
610
611 /// Push the global environment onto the stack.
612 pub fn push_global_table(&self) {
613 unsafe { lua_pushglobaltable(self.as_ptr()) }
614 }
615
616 /// Push an [`Integer`] onto the stack.
617 pub fn push_integer(&self, value: Integer) {
618 unsafe { lua_pushinteger(self.as_ptr(), value) }
619 }
620
621 /// Push a light userdata onto the stack.
622 ///
623 /// A light userdata represents a plain pointer.
624 /// It is a value, like a number:
625 /// it is not created, it has no individual metatable,
626 /// and it is not collected (as it was never created).
627 ///
628 /// A light userdata is equal to any light userdata with the same C address.
629 ///
630 /// # Safety
631 /// `ptr` can be used arbitrarily in Lua,
632 /// so this method should only be used for trusted code.
633 pub unsafe fn push_light_userdata(&self, ptr: *mut c_void) {
634 unsafe { lua_pushlightuserdata(self.as_ptr(), ptr) }
635 }
636
637 /// Works the same as [`Thread::push_string`], however it accepts
638 /// [`c_char`]s instead of [`u8`]s.
639 ///
640 /// # Errors
641 /// The underlying Lua state may raise a memory [error](crate::errors).
642 pub fn push_c_chars<'l>(&'l self, data: &[c_char]) -> &'l [c_char] {
643 let length = data.len();
644 unsafe { from_raw_parts(
645 lua_pushlstring(self.as_ptr(), data.as_ptr(), length),
646 length
647 ) }
648 }
649
650 /// Push a string onto the stack.
651 ///
652 /// The string can contain any binary data, including embedded zeros.
653 ///
654 /// Lua will make or reuse an internal copy of the given string, so the
655 /// memory pointed to by `data` can be safely freed or reused immediately
656 /// after the function returns.
657 ///
658 /// See also [`Thread::push_c_chars`].
659 ///
660 /// # Errors
661 /// The underlying Lua state may raise a memory [error](crate::errors).
662 pub fn push_string(&self, data: impl AsRef<[u8]>) -> &[u8] {
663 let slice = data.as_ref();
664 let length = slice.len();
665 unsafe { from_raw_parts(
666 lua_pushlstring(
667 self.as_ptr(),
668 slice.as_ptr() as *const _, length
669 ) as *const _,
670 length
671 ) }
672 }
673
674 /// Push `nil` onto the stack.
675 pub fn push_nil(&self) {
676 unsafe { lua_pushnil(self.as_ptr()) }
677 }
678
679 /// Push a [`Number`] onto the stack.
680 pub fn push_number(&self, value: Number) {
681 unsafe { lua_pushnumber(self.as_ptr(), value) }
682 }
683
684 /// Push a zero-terminated string onto the stack.
685 ///
686 /// Lua will make or reuse an internal copy of the given string, so the
687 /// memory pointed to by `data` can be freed or reused immediately after the
688 /// function returns.
689 ///
690 /// See also [`Thread::push_c_chars`] and [`Thread::push_string`].
691 ///
692 /// # Errors
693 /// The underlying Lua state may raise a memory [error](crate::errors).
694 pub fn push_c_str<'l>(&'l self, data: &CStr) -> &'l CStr {
695 unsafe { CStr::from_ptr(
696 lua_pushstring(self.as_ptr(), data.as_ptr())
697 ) }
698 }
699
700 /// Push the Lua thread represented by this [`Thread`] onto its own stack,
701 /// and return `true` if this thread is the main thread
702 /// (see also [`Lua`](crate::Lua)).
703 pub fn push_thread(&self) -> bool {
704 (unsafe { lua_pushthread(self.as_ptr()) }) != 0
705 }
706
707 /// Push a copy of the element at the given index onto the stack.
708 pub fn push_value(&self, index: c_int) {
709 unsafe { lua_pushvalue(self.as_ptr(), index) }
710 }
711
712 /// Return `true` if the two values in indices `idx_a` and `idx_b` are
713 /// primitively equal (that is, equal without calling the `__eq` metamethod).
714 ///
715 /// This also returns `false` if any of the indices are not valid.
716 pub fn raw_equal(&self, idx_a: c_int, idx_b: c_int) -> bool {
717 (unsafe { lua_rawequal(self.as_ptr(), idx_a, idx_b) }) != 0
718 }
719
720 /// Without calling metamethods, push `t[k]`, where `t` is the value at the
721 /// given index and `k` is the value on the top of the stack.
722 ///
723 /// # Safety
724 /// The value at `tbl_index` must be a table.
725 pub unsafe fn raw_get(&self, tbl_index: c_int) -> Type {
726 unsafe { Type::from_c_int_unchecked(
727 lua_rawget(self.as_ptr(), tbl_index)
728 ) }
729 }
730
731 /// Without calling metamethods, push `t[i]`, where `t` is the value at the
732 /// given index.
733 ///
734 /// # Safety
735 /// The value at `tbl_index` must be a table.
736 pub unsafe fn raw_get_i(&self, tbl_index: c_int, i: Integer) -> Type {
737 unsafe { Type::from_c_int_unchecked(
738 lua_rawgeti(self.as_ptr(), tbl_index, i)
739 ) }
740 }
741
742 /// Without calling metamethods, push `t[ptr]`, where `t` is the value at
743 /// the given index and `ptr` is the given pointer represented as a light
744 /// userdata.
745 ///
746 /// # Safety
747 /// The value at `tbl_index` must be a table.
748 pub unsafe fn raw_get_p(&self, tbl_index: c_int, ptr: *const c_void) -> Type {
749 unsafe { Type::from_c_int_unchecked(
750 lua_rawgetp(self.as_ptr(), tbl_index, ptr)
751 ) }
752 }
753
754 /// Return the raw "length" of the value at the given index.
755 ///
756 /// For strings, this is the string length;
757 /// for tables, this is the result of the length operator (`#`) with no
758 /// metamethods;
759 /// for userdata, this is the size of the block of memory allocated for the
760 /// userdata.
761 /// For other values, this call returns `0`.
762 pub fn raw_length(&self, index: c_int) -> Unsigned {
763 unsafe { lua_rawlen(self.as_ptr(), index) }
764 }
765
766 /// Without metamethods, do `t[k] = v`, where `t` is the value at the given
767 /// index, `v` is the value on the top of the stack, and `k` is the value
768 /// just below the top.
769 ///
770 /// # Errors
771 /// The underlying Lua state may raise a memory [error](crate::errors).
772 ///
773 /// # Safety
774 /// The value at `tbl_index` must be a table.
775 pub unsafe fn raw_set(&self, tbl_index: c_int) {
776 unsafe { lua_rawset(self.as_ptr(), tbl_index) }
777 }
778
779 /// Without metamethods, do `t[i] = v`, where `t` is the value at the given
780 /// index and `v` is the value on the top of the stack.
781 ///
782 /// # Errors
783 /// The underlying Lua state may raise a memory [error](crate::errors).
784 ///
785 /// # Safety
786 /// The value at `tbl_index` must be a table.
787 pub unsafe fn raw_set_i(&self, tbl_index: c_int, i: Integer) {
788 unsafe { lua_rawseti(self.as_ptr(), tbl_index, i) }
789 }
790
791 /// Without metamethods, do `t[ptr] = v`, where `t` is the value at the
792 /// given index, `v` is the value on the top of the stack, and `ptr` is the
793 /// given pointer represented as a light userdata.
794 ///
795 /// # Errors
796 /// The underlying Lua state may raise a memory [error](crate::errors).
797 ///
798 /// # Safety
799 /// The value at `tbl_index` must be a table.
800 pub unsafe fn raw_set_p(&self, tbl_index: c_int, ptr: *const c_void) {
801 unsafe { lua_rawsetp(self.as_ptr(), tbl_index, ptr) }
802 }
803
804 /// Set the C function `func` as the new value of global `name`.
805 ///
806 /// # Errors
807 /// The underlying Lua state may raise an arbitrary [error](crate::errors).
808 pub fn register(&self, name: &CStr, func: CFunction) {
809 unsafe { lua_register(self.as_ptr(), name.as_ptr(), func) }
810 }
811
812 /// Remove the element at the given valid index, shifting down the elements
813 /// above this index to fill the gap.
814 ///
815 /// This function cannot be called with a pseudo-index, because a
816 /// pseudo-index is not an actual stack position.
817 pub fn remove(&self, index: c_int) {
818 unsafe { lua_remove(self.as_ptr(), index) }
819 }
820
821 /// Move the top element into the given valid index without shifting any
822 /// element (therefore replacing the value at that given index),
823 /// and then pop that top element.
824 pub fn replace(&self, index: c_int) {
825 unsafe { lua_replace(self.as_ptr(), index) }
826 }
827
828 /// Rotate the stack elements between the valid index `index` and the top of
829 /// the stack.
830 ///
831 /// The elements are rotated `n` positions in the direction of the top for a
832 /// ositive `n`, or `-n` positions in the direction of the bottom for a
833 /// negative `n`.
834 /// The absolute value of `n` must not be greater than the size of the slice
835 /// being rotated.
836 ///
837 /// This function cannot be called with a pseudo-index, because a
838 /// pseudo-index is not an actual stack position.
839 pub fn rotate(&self, index: c_int, n_values: c_int) {
840 unsafe { lua_rotate(self.as_ptr(), index, n_values) }
841 }
842
843 /// Pop a value from the stack and set it as the new value of global `name`.
844 ///
845 /// # Errors
846 /// The underlying Lua state may raise an arbitrary [error](crate::errors).
847 pub fn set_global(&self, key: &CStr) {
848 unsafe { lua_setglobal(self.as_ptr(), key.as_ptr()) }
849 }
850
851 /// Pop a value from the stack and set it as the new `n`-th user value
852 /// associated to the full userdata at the given index.
853 ///
854 /// Returns `false` if the userdata does not have that value.
855 pub fn set_i_uservalue(&self, ud_index: c_int, n: c_int) -> bool {
856 (unsafe { lua_setiuservalue(self.as_ptr(), ud_index, n) }) != 0
857 }
858
859 /// Pop a table or `nil` from the stack and sets that value as the new
860 /// metatable for the value at the given index. (`nil` means no metatable.)
861 // NOTE: `lua_setmetatable` always returns a `1`, which isn't useful.
862 pub fn set_metatable(&self, obj_index: c_int) {
863 unsafe { lua_setmetatable(self.as_ptr(), obj_index) };
864 }
865
866 /// Set the warning function to be used by Lua to emit warnings
867 /// (see [`WarnFunction`]).
868 ///
869 /// See also [`Thread::remove_warn_fn`].
870 ///
871 /// # Safety
872 /// `warn_data` is the custom data to be passed to the warning function.
873 /// It must be valid for `warn`.
874 pub unsafe fn set_warn_fn(&self, warn: WarnFunction, warn_data: *mut c_void) {
875 unsafe { lua_setwarnf(self.as_ptr(), Some(warn), warn_data) }
876 }
877
878 /// Remove the warning function to be used by Lua to emit warnings.
879 ///
880 /// See also [`Thread::set_warn_fn`].
881 pub fn remove_warn_fn(&self) {
882 unsafe { lua_setwarnf(self.as_ptr(), None, null_mut()) }
883 }
884
885 /// Return the status of the Lua thread represented by this [`Thread`].
886 ///
887 /// The status can be [`Status::Ok`] for a normal thread, an error variant
888 /// if the thread finished the execution of a [`Managed::resume`] with an
889 /// error, or [`Status::Yielded`] if the thread is suspended.
890 ///
891 /// Functions can only be called in threads with status [`Status::Ok`].
892 /// Threads with status [`Status::Ok`] or [`Status::Yielded`] can be resumed
893 /// (to start a new coroutine or resume an existing one).
894 pub fn status(&self) -> Status {
895 unsafe { Status::from_c_int_unchecked(lua_status(self.as_ptr())) }
896 }
897
898 /// Convert the Lua value at the given index to a [`bool`].
899 ///
900 /// Like all tests in Lua, this returns `true` for any Lua value different
901 /// from `false` and `nil`; otherwise it returns `false`.
902 ///
903 /// If you want to accept only actual boolean values, use
904 /// [`Thread::is_boolean`] to test the value's type first.
905 pub fn to_boolean(&self, idx: c_int) -> bool {
906 (unsafe { lua_toboolean(self.as_ptr(), idx) }) != 0
907 }
908
909 /// Convert a value at the given index to a C function.
910 /// If it is not one, return `None`.
911 pub fn to_c_function(&self, index: c_int) -> Option<CFunction> {
912 unsafe { lua_tocfunction(self.as_ptr(), index) }
913 }
914
915 /// Mark the given index in the stack as a to-be-closed slot.
916 ///
917 /// Like a to-be-closed variable in Lua, the value at that slot in the stack
918 /// will be closed when it goes out of scope.
919 /// Here, in the context of a C function, to go out of scope means that the
920 /// running function returns to Lua, or there is an error, or the slot is
921 /// removed from the stack through [`Managed::set_top`] or [`Managed::pop`],
922 /// or there is a call to [`Managed::close_slot`].
923 ///
924 /// A slot marked as to-be-closed should not be removed from the stack by
925 /// any other function in the API except [`Managed::set_top`] or
926 /// [`Managed::pop`], unless previously deactivated by [`Managed::close_slot`].
927 ///
928 /// # Errors
929 /// The underlying Lua state may raise a memory [error](crate::errors).
930 ///
931 /// # Safety
932 /// This function should not be called for an index that is equal to or
933 /// below an active to-be-closed slot.
934 ///
935 /// Note that, both in case of errors and of a regular return, by the time
936 /// the `__close` metamethod runs, the C stack was already unwound, so that
937 /// any automatic C variable declared in the calling function
938 /// (e.g., a buffer) will be out of scope.
939 pub unsafe fn to_close(&self, index: c_int) {
940 unsafe { lua_toclose(self.as_ptr(), index) }
941 }
942
943 /// This behaves exactly the same as [`Thread::to_integer_opt`], however the
944 /// return value is `0` if an integer isn't present.
945 pub fn to_integer(&self, idx: c_int) -> Integer {
946 unsafe { lua_tointeger(self.as_ptr(), idx) }
947 }
948
949 /// Convert the Lua value at the given index to the signed integral type
950 /// [`Integer`].
951 ///
952 /// The Lua value must be an integer, or a number or string convertible to
953 /// an integer. Otherwise, this function returns `None`.
954 pub fn to_integer_opt(&self, idx: c_int) -> Option<Integer> {
955 let mut is_num = 0;
956 let result = unsafe { lua_tointegerx(self.as_ptr(), idx, &mut is_num as *mut _) };
957 (is_num != 0).then_some(result)
958 }
959
960 /// Convert the Lua value at the given index to a slice of [`c_char`]s,
961 /// representing a Lua string.
962 ///
963 /// This function works like [`Thread::to_string`].
964 ///
965 /// # Errors
966 /// The underlying Lua state may raise a memory [error](crate::errors).
967 pub fn to_c_chars(&self, index: c_int) -> Option<&[c_char]> {
968 let mut len = 0;
969 let str_ptr = unsafe { lua_tolstring(self.as_ptr(), index, &mut len as *mut _) };
970 if !str_ptr.is_null() {
971 Some(unsafe { from_raw_parts(str_ptr, len) })
972 } else {
973 None
974 }
975 }
976
977 /// Convert the Lua value at the given index to a [`CStr`],
978 /// representing a Lua string.
979 ///
980 /// This function works like [`Thread::to_string`].
981 ///
982 /// # Errors
983 /// The underlying Lua state may raise a memory [error](crate::errors).
984 pub fn to_c_str(&self, index: c_int) -> Option<&CStr> {
985 let str_ptr = unsafe { lua_tostring(self.as_ptr(), index) };
986 if !str_ptr.is_null() {
987 Some(unsafe { CStr::from_ptr(str_ptr) })
988 } else {
989 None
990 }
991 }
992
993 /// Convert the Lua value at the given index to a slice of [`u8`]s,
994 /// representing a Lua string.
995 ///
996 /// The Lua value must be a string or a number; otherwise, the function
997 /// returns `None`.
998 ///
999 /// If the value is a number, then this function also changes the *actual
1000 /// value in the stack* to a string.
1001 ///
1002 /// The function returns a slice to data inside the Lua state.
1003 /// This string always has a zero (`'\0'`) after its last character (as in C),
1004 /// but can contain other zeros in its body.
1005 ///
1006 /// # Errors
1007 /// The underlying Lua state may raise a memory [error](crate::errors).
1008 pub fn to_string(&self, index: c_int) -> Option<&[u8]> {
1009 let mut len = 0;
1010 let str_ptr = unsafe { lua_tolstring(self.as_ptr(), index, &mut len as *mut _) };
1011 if !str_ptr.is_null() {
1012 Some(unsafe { from_raw_parts(str_ptr as *const _, len) })
1013 } else {
1014 None
1015 }
1016 }
1017
1018 /// This behaves exactly the same as [`Thread::to_number_opt`], however the
1019 /// return value is `0.0` if a number isn't present.
1020 pub fn to_number(&self, idx: c_int) -> Number {
1021 unsafe { lua_tonumber(self.as_ptr(), idx) }
1022 }
1023
1024 /// Convert the Lua value at the given index to the floating-point number
1025 /// type [`Number`].
1026 ///
1027 /// The Lua value must be a number or string convertible to a number.
1028 /// Otherwise, this function returns `None`.
1029 pub fn to_number_opt(&self, idx: c_int) -> Option<Number> {
1030 let mut is_num = 0;
1031 let result = unsafe { lua_tonumberx(self.as_ptr(), idx, &mut is_num as *mut _) };
1032 (is_num != 0).then_some(result)
1033 }
1034
1035 /// Convert the value at the given index to a generic C pointer
1036 /// ([`*const c_void`](c_void)).
1037 ///
1038 /// The value can be a userdata, a table, a thread, a string, or a function;
1039 /// otherwise, this function returns null.
1040 ///
1041 /// Different objects will give different pointers.
1042 /// There is no way to convert the pointer back to its original value.
1043 ///
1044 /// Typically this function is used only for hashing and debug information.
1045 pub fn to_pointer(&self, idx: c_int) -> *const c_void {
1046 unsafe { lua_topointer(self.as_ptr(), idx) }
1047 }
1048
1049 /// Convert the value at the given index to a Lua thread, represented by a
1050 /// `*mut`[`State`].
1051 ///
1052 /// The value must be a thread; otherwise, the function returns null.
1053 pub fn to_thread(&self, index: c_int) -> *mut State {
1054 unsafe { lua_tothread(self.as_ptr(), index) }
1055 }
1056
1057 /// If the value at the given index is a light or full userdata, return the
1058 /// address it represents. Otherwise, return null.
1059 pub fn to_userdata(&self, idx: c_int) -> *mut c_void {
1060 unsafe { lua_touserdata(self.as_ptr(), idx) }
1061 }
1062
1063 /// Return the type of the value in the given valid index, or [`Type::None`]
1064 /// for a non-valid but acceptable index.
1065 pub fn type_of(&self, idx: c_int) -> Type {
1066 unsafe { Type::from_c_int_unchecked(lua_type(self.as_ptr(), idx)) }
1067 }
1068
1069 /// Return the name of the type encoded by `type_tag`.
1070 pub fn type_name(&self, type_tag: Type) -> &CStr {
1071 unsafe { CStr::from_ptr(lua_typename(self.as_ptr(), type_tag as _)) }
1072 }
1073
1074 /// Return the version number of the Lua core.
1075 pub fn version(&self) -> Number {
1076 unsafe { lua_version(self.as_ptr()) }
1077 }
1078
1079 /// Emit a warning with the given message.
1080 ///
1081 /// A message in a call with `to_be_continued == true` should be continued
1082 /// in another call to this function.
1083 pub fn warning(&self, message: &CStr, to_be_continued: bool) {
1084 unsafe { lua_warning(
1085 self.as_ptr(), message.as_ptr(), if to_be_continued { 1 } else { 0 }
1086 ) }
1087 }
1088
1089 /// Exchange values between different threads of the same state.
1090 ///
1091 /// This function pops `n_values` values from the stack of this thread, and
1092 /// pushes them onto the stack of the thread `to`.
1093 pub fn xmove(&self, to: &Self, n_values: c_uint) {
1094 unsafe { lua_xmove(self.as_ptr(), to.as_ptr(), n_values as _) }
1095 }
1096
1097 /// This behaves exactly like [`Thread::yield_k_with`], however there is no
1098 /// continuation.
1099 ///
1100 /// # Safety
1101 /// This function should be called *only* outside of hooks.
1102 /// It is Undefined Behavior if the code after a call to this function is
1103 /// reachable.
1104 pub unsafe fn yield_with(&self, n_results: c_int) -> ! {
1105 unsafe { lua_yield(self.as_ptr(), n_results) }
1106 }
1107
1108 /// This behaves exactly like [`Thread::yield_in_hook_k_with`], however
1109 /// there is no continuation.
1110 ///
1111 /// # Safety
1112 /// This function should be called *only* outside of hooks.
1113 /// It is Undefined Behavior if the code after a call to this function is
1114 /// unreachable.
1115 pub unsafe fn yield_in_hook_with(&self, n_results: c_int) {
1116 unsafe { lua_yield_in_hook(self.as_ptr(), n_results) };
1117 }
1118
1119 /// Yield this thread (like a coroutine).
1120 ///
1121 /// When this function is called, the running coroutine suspends its
1122 /// execution, and the call to [`Managed::resume`] that started this
1123 /// coroutine returns.
1124 ///
1125 /// The parameter `n_results` is the number of values from the stack that
1126 /// will be passed as results to [`Managed::resume`].
1127 ///
1128 /// When the coroutine is resumed again, Lua calls the given continuation
1129 /// function `continuation` to continue the execution of the C function that
1130 /// yielded.
1131 /// This continuation function receives the same stack from the previous
1132 /// function, with the `n_results` results removed and replaced by the
1133 /// arguments passed to [`Managed::resume`].
1134 /// Moreover, the continuation function receives the value `context` that
1135 /// was originally passed.
1136 ///
1137 /// Usually, this function does not return; when the coroutine eventually
1138 /// resumes, it continues executing the continuation function.
1139 /// However, there is one special case, which is when this function is
1140 /// called from inside a line or a count hook (see [`Hook`]).
1141 /// In that case, [`Thread::yield_in_hook_with`] should be called
1142 /// (thus, no continuation) and no results, and the hook should return
1143 /// immediately after the call.
1144 /// Lua will yield and, when the coroutine resumes again, it will continue
1145 /// the normal execution of the (Lua) function that triggered the hook.
1146 ///
1147 /// # Errors
1148 /// The underlying Lua thread can raise an error
1149 /// if the function is called from a thread with a pending C call
1150 /// with no continuation function (what is called a C-call boundary),
1151 /// or it is called from a thread that is not running inside a resume
1152 /// (typically the main thread).
1153 ///
1154 /// # Safety
1155 /// This function should be called *only* outside of hooks.
1156 /// It is Undefined Behavior if the code after a call to this function is
1157 /// reachable.
1158 pub unsafe fn yield_k_with(
1159 &self, n_results: c_int,
1160 continuation: KFunction, context: KContext
1161 ) -> ! {
1162 unsafe { lua_yieldk(self.as_ptr(), n_results, context, Some(continuation)) }
1163 }
1164
1165 /// This behaves exactly like [`Thread::yield_k_with`], however it should
1166 /// only be called in hooks.
1167 ///
1168 /// # Errors
1169 /// The underlying Lua thread can raise an error
1170 /// if the function is called from a thread with a pending C call
1171 /// with no continuation function (what is called a C-call boundary),
1172 /// or it is called from a thread that is not running inside a resume
1173 /// (typically the main thread).
1174 ///
1175 /// # Safety
1176 /// This function should be called *only* inside of hooks.
1177 pub unsafe fn yield_in_hook_k_with(
1178 &self, n_results: c_int,
1179 continuation: KFunction, context: KContext
1180 ) {
1181 unsafe { lua_yieldk_in_hook(
1182 self.as_ptr(), n_results,
1183 context, Some(continuation)
1184 ) };
1185 }
1186
1187 /// Returns a [`ThreadDebug`] structure that exposes various functions operating on [`struct@Debug`] structures.
1188 ///
1189 /// # Safety
1190 /// `ID_SIZE` must be the appropriate identifier size for the underlying Lua state.
1191 /// See [`DEFAULT_ID_SIZE`] for the default.
1192 pub const unsafe fn debug<const ID_SIZE: usize>(&self) -> ThreadDebug<'_, ID_SIZE> {
1193 ThreadDebug {
1194 thread: self,
1195 }
1196 }
1197
1198 /// Return the current hook count.
1199 pub fn hook_count(&self) -> c_int {
1200 unsafe { lua_gethookcount(self.as_ptr()) }
1201 }
1202
1203 /// Return the current hook mask.
1204 ///
1205 /// See also [`HookMask`].
1206 pub fn hook_mask(&self) -> HookMask {
1207 unsafe { HookMask::from_c_int_unchecked(lua_gethookmask(self.as_ptr())) }
1208 }
1209
1210 /// Get information about the `n`-th upvalue of the closure at index
1211 /// `func_index`.
1212 ///
1213 /// This function pushes the upvalue's value onto the stack and returns its
1214 /// name. Returns `None` (and pushes nothing) when the index `n` is greater
1215 /// than the number of upvalues.
1216 pub fn get_upvalue(&self, func_index: c_int, n: u8) -> Option<&CStr> {
1217 let str_ptr = unsafe { lua_getupvalue(self.as_ptr(), func_index, n as _) };
1218 if !str_ptr.is_null() {
1219 Some(unsafe { CStr::from_ptr(str_ptr) })
1220 } else {
1221 None
1222 }
1223 }
1224
1225 /// Set the value of a closure's upvalue and return its name.
1226 ///
1227 /// Returns `None` (and pops nothing) when the index `n` is greater than the
1228 /// number of upvalues.
1229 ///
1230 /// This function assigns the value on the top of the stack to the upvalue.
1231 /// It also pops the value from the stack.
1232 pub fn set_upvalue(&self, func_index: c_int, n: u8) -> Option<&CStr> {
1233 let name_ptr = unsafe { lua_setupvalue(self.as_ptr(), func_index, n as _) };
1234 if !name_ptr.is_null() {
1235 unsafe { Some(CStr::from_ptr(name_ptr)) }
1236 } else {
1237 None
1238 }
1239 }
1240
1241 /// Return a unique identifier for the upvalue numbered `n` from the closure
1242 /// at index `func_index`.
1243 ///
1244 /// These unique identifiers allow a program to check whether different
1245 /// closures share upvalues.
1246 /// Lua closures that share an upvalue (that is, that access a same external
1247 /// local variable) will return identical ids for those upvalue indices.
1248 ///
1249 /// # Safety
1250 /// The returned pointer may only be used for comparisons.
1251 pub unsafe fn upvalue_id(&self, func_index: c_int, n: u8) -> *mut c_void {
1252 unsafe { lua_upvalueid(self.as_ptr(), func_index, n as _) }
1253 }
1254
1255 /// Make the
1256 /// `n_into`-th upvalue of the Lua closure at index `func_into_index`
1257 /// refer to the
1258 /// `n_from`-th upvalue of the Lua closure at index `func_from_index`.
1259 pub fn upvalue_join(
1260 &self,
1261 func_into_index: i32, n_into: u8,
1262 func_from_index: i32, n_from: u8,
1263 ) {
1264 unsafe { lua_upvaluejoin(
1265 self.as_ptr(),
1266 func_into_index, n_into as _,
1267 func_from_index, n_from as _
1268 ) }
1269 }
1270}
1271
1272#[cfg(feature = "auxlib")]
1273impl Thread {
1274 /// Construct a new [`Buffer`] that's initialized with this [`Thread`].
1275 pub fn new_buffer(&self) -> Buffer<'_> {
1276 unsafe { Buffer::new_in_raw(self.as_ptr()) }
1277 }
1278
1279 /// Raise an error reporting a problem with argument arg of the C function
1280 /// that called it, using a standard message that includes `extra_message`
1281 /// as a comment:
1282 ///
1283 /// `bad argument #<argument> to '<function name>' (<message>)`
1284 ///
1285 /// This function never returns.
1286 pub fn arg_error(&self, arg: c_int, extra_message: &CStr) -> ! {
1287 unsafe { luaL_argerror(self.as_ptr(), arg, extra_message.as_ptr()) }
1288 }
1289
1290 /// Check whether the function has an argument of any type (including `nil`)
1291 /// at position `arg`.
1292 ///
1293 /// # Errors
1294 /// The underlying Lua state may raise an [error](crate::errors) if the
1295 /// argument `arg`'s type is incorrect.
1296 pub fn check_any(&self, arg: c_int) {
1297 unsafe { luaL_checkany(self.as_ptr(), arg) }
1298 }
1299
1300 /// Check whether the function argument `arg` is an integer (or can be
1301 /// converted to an integer) and return this integer.
1302 ///
1303 /// # Errors
1304 /// The underlying Lua state may raise an [error](crate::errors) if the
1305 /// argument `arg`'s type is incorrect.
1306 pub fn check_integer(&self, arg: c_int) -> Integer {
1307 unsafe { luaL_checkinteger(self.as_ptr(), arg) }
1308 }
1309
1310 /// Check whether the function argument `arg` is a string and returns this
1311 /// string represented as a slice of [`c_char`]s.
1312 ///
1313 /// # Errors
1314 /// The underlying Lua state may raise an [error](crate::errors) if the
1315 /// argument `arg` isn't a string.
1316 pub fn check_c_chars(&self, arg: c_int) -> &[c_char] {
1317 let mut len = 0;
1318 let str_ptr = unsafe { luaL_checklstring(self.as_ptr(), arg, &mut len as *mut _) };
1319 unsafe { from_raw_parts(str_ptr, len) }
1320 }
1321
1322 /// Works the same as [`Thread::check_c_chars`], however it returns a slice
1323 /// of [`u8`]s instead of [`c_char`]s.
1324 ///
1325 /// # Errors
1326 /// The underlying Lua state may raise an [error](crate::errors) if the
1327 /// argument `arg` isn't a string.
1328 pub fn check_string(&self, arg: c_int) -> &[u8] {
1329 let mut len = 0;
1330 let str_ptr = unsafe { luaL_checklstring(self.as_ptr(), arg, &mut len as *mut _) };
1331 unsafe { from_raw_parts(str_ptr as *const _, len) }
1332 }
1333
1334 /// Check whether the function argument `arg` is a number and return this
1335 /// number converted to a [`Number`].
1336 ///
1337 /// # Errors
1338 /// The underlying Lua state may raise an [error](crate::errors) if the
1339 /// argument `arg`'s type is incorrect.
1340 pub fn check_number(&self, arg: c_int) -> Number {
1341 unsafe { luaL_checknumber(self.as_ptr(), arg) }
1342 }
1343
1344 /// Check whether the function argument `arg` is a string, search for this
1345 /// string in the option list `list` and return the index in the list where
1346 /// the string was found.
1347 ///
1348 /// If `default` is `Some`, the function uses it as a default value when
1349 /// there is no argument `arg` or when this argument is `nil`.
1350 ///
1351 /// This is a useful function for mapping strings to C enums.
1352 /// (The usual convention in Lua libraries is to use strings instead of
1353 /// numbers to select options.)
1354 ///
1355 /// # Errors
1356 /// The underlying Lua state may raise an [error](crate::errors) if the
1357 /// argument `arg` is not a string or if the string cannot be found in `list`.
1358 pub fn check_option<const N: usize>(
1359 &self, arg: c_int,
1360 default: Option<&CStr>,
1361 list: &AuxOptions<'_, N>
1362 ) -> usize {
1363 (unsafe { luaL_checkoption(
1364 self.as_ptr(), arg,
1365 default.map(|cstr| cstr.as_ptr()).unwrap_or(null()),
1366 list.as_ptr()
1367 ) }) as _
1368 }
1369
1370 /// Grow the stack size to `top + size` elements, raising an error if the
1371 /// stack cannot grow to that size.
1372 ///
1373 /// `message` is an additional text to go into the error message
1374 /// (or `None` for no additional text).
1375 ///
1376 /// # Errors
1377 /// The underlying Lua state may raise an [error](crate::errors) if the
1378 /// Lua stack cannot grow to the given size.
1379 pub fn check_stack(&self, size: c_int, message: Option<&CStr>) {
1380 unsafe { luaL_checkstack(
1381 self.as_ptr(),
1382 size,
1383 message.map(|cstr| cstr.as_ptr()).unwrap_or(null())
1384 ) }
1385 }
1386
1387 /// Check whether the function argument `arg` is a string and return this
1388 /// string represented by a [`CStr`].
1389 ///
1390 /// # Errors
1391 /// The underlying Lua state may raise an [error](crate::errors) if the
1392 /// argument `arg` isn't a string.
1393 pub fn check_c_str(&self, arg: c_int) -> &CStr {
1394 let str_ptr = unsafe { luaL_checkstring(self.as_ptr(), arg) };
1395 unsafe { CStr::from_ptr(str_ptr) }
1396 }
1397
1398 /// Check whether the function argument `arg` has type `type_tag`.
1399 ///
1400 /// See also [`Type`].
1401 ///
1402 /// # Errors
1403 /// The underlying Lua state may raise an [error](crate::errors) if the
1404 /// argument `arg`'s type is incorrect.
1405 pub fn check_type(&self, arg: c_int, type_tag: Type) {
1406 unsafe { luaL_checktype(self.as_ptr(), arg, type_tag as _) }
1407 }
1408
1409 /// Check whether the function argument `arg` is a userdata of the type
1410 /// `table_name` (see also [`Thread::new_metatable`]) and return the
1411 /// userdata's memory-block address (see [`Thread::to_userdata`]).
1412 ///
1413 /// # Errors
1414 /// The underlying Lua state may raise an [error](crate::errors) if the
1415 /// argument `arg`'s type is incorrect.
1416 ///
1417 /// # Safety
1418 /// The returned pointer must only be used while it's valid.
1419 ///
1420 /// While the metatable of userdata is protected from modification in the Lua standard library,
1421 /// an unsound implementation of setting the metatable of an object in Lua could change a userdatum's metatable
1422 /// and make the check for the `table_name` metatable unsound.
1423 pub unsafe fn check_udata(&self, arg: c_int, table_name: &CStr) -> NonNull<c_void> {
1424 unsafe { NonNull::new_unchecked(luaL_checkudata(self.as_ptr(), arg, table_name.as_ptr())) }
1425 }
1426
1427 /// Check whether the code making the call and the Lua library being called
1428 /// are using the same version of Lua and the same numeric types.
1429 ///
1430 /// # Errors
1431 /// The underlying Lua state may raise an [error](crate::errors) if the
1432 /// above requirements aren't met.
1433 pub fn check_version(&self) {
1434 unsafe { luaL_checkversion(self.as_ptr()) }
1435 }
1436
1437 /// Raise an error.
1438 ///
1439 /// This function adds the file name and the line number where the error
1440 /// occurred at the beginning of `message`, if this information is available.
1441 ///
1442 /// This function never returns.
1443 pub fn error_c_str(&self, message: &CStr) -> ! {
1444 unsafe { luaL_error(
1445 self.as_ptr(),
1446 c"%s".as_ptr(),
1447 message.as_ptr()
1448 ) }
1449 }
1450
1451 /// Produce the return values for process-related functions in the standard
1452 /// library (`os.execute` and `io.close`).
1453 ///
1454 /// # Errors
1455 /// The underlying Lua state may raise a memory [error](crate::errors).
1456 pub fn exec_result(&self, status: c_int) -> c_int {
1457 unsafe { luaL_execresult(self.as_ptr(), status) }
1458 }
1459
1460 /// Produce the return values for file-related functions in the standard
1461 /// library (`io.open`, `os.rename`, `file:seek`, etc.).
1462 ///
1463 /// # Errors
1464 /// The underlying Lua state may raise a memory [error](crate::errors).
1465 pub fn file_result(&self, status: c_int, file_name: &CStr) -> c_int {
1466 unsafe { luaL_fileresult(self.as_ptr(), status, file_name.as_ptr()) }
1467 }
1468
1469 /// Push onto the stack the field `event` from the metatable of the object
1470 /// at index `obj_index` and return the type of the pushed value.
1471 ///
1472 /// If the object does not have a metatable, or if the metatable does not
1473 /// have this field, this function pushes nothing and returns [`Type::Nil`].
1474 ///
1475 /// # Errors
1476 /// The underlying Lua state may raise a memory [error](crate::errors).
1477 pub fn get_meta_field(&self, obj_index: c_int, event: &CStr) -> Type {
1478 unsafe { Type::from_c_int_unchecked(luaL_getmetafield(
1479 self.as_ptr(), obj_index, event.as_ptr()
1480 )) }
1481 }
1482
1483 /// Push onto the stack the metatable associated with the name `table_name`
1484 /// in the registry (see also [`Thread::new_metatable`]), or `nil` if there
1485 /// is no metatable associated with that name, and return the type of the
1486 /// pushed value.
1487 ///
1488 /// # Errors
1489 /// The underlying Lua state may raise a memory [error](crate::errors).
1490 pub fn get_aux_metatable(&self, table_name: &CStr) -> Type {
1491 unsafe { Type::from_c_int_unchecked(luaL_getmetatable(
1492 self.as_ptr(), table_name.as_ptr()
1493 )) }
1494 }
1495
1496 /// Load a buffer as a Lua chunk.
1497 ///
1498 /// This function works like [`Thread::load_string`].
1499 pub fn load_c_chars(&self, buffer: &[c_char], name: &CStr) -> Status {
1500 unsafe { Status::from_c_int_unchecked(
1501 luaL_loadbuffer(
1502 self.as_ptr(),
1503 buffer.as_ptr(), buffer.len(),
1504 name.as_ptr()
1505 )
1506 ) }
1507 }
1508
1509 /// Load a buffer as a Lua chunk.
1510 ///
1511 /// This function uses [`Thread::load`] to load the chunk in the buffer
1512 /// pointed to by `buffer`, and will return the same results as that
1513 /// function.
1514 ///
1515 /// `name` is the chunk name, used for debug information and error messages.
1516 // /// The string mode works as in the function lua_load.
1517 pub fn load_string(&self, buffer: impl AsRef<[u8]>, name: &CStr) -> Status {
1518 let slice = buffer.as_ref();
1519 unsafe { Status::from_c_int_unchecked(
1520 luaL_loadbuffer(
1521 self.as_ptr(),
1522 slice.as_ptr() as *const _, slice.len(),
1523 name.as_ptr()
1524 )
1525 ) }
1526 }
1527
1528 /// Load a file as a Lua chunk.
1529 ///
1530 /// This function uses [`Thread::load`] to load the chunk in the file
1531 /// `file_name`.
1532 ///
1533 /// The first line in the file is ignored if it starts with a #.
1534 ///
1535 /// # Errors
1536 /// The underlying Lua state may raise a memory [error](crate::errors).
1537 pub fn load_file(&self, file_name: &CStr) -> Status {
1538 unsafe { Status::from_c_int_unchecked(
1539 luaL_loadfile(self.as_ptr(), file_name.as_ptr())
1540 ) }
1541 }
1542
1543 /// Load a Lua chunk from the standard input.
1544 ///
1545 /// This function uses [`Thread::load`] to load the chunk.
1546 ///
1547 /// The first line in the file is ignored if it starts with a `#`.
1548 ///
1549 /// # Errors
1550 /// The underlying Lua state may raise a memory [error](crate::errors).
1551 pub fn load_stdin(&self) -> Status {
1552 unsafe { Status::from_c_int_unchecked(
1553 luaL_loadfile(self.as_ptr(), null())
1554 ) }
1555 }
1556
1557 /// Load a string as a Lua chunk.
1558 ///
1559 /// This function uses [`Thread::load`] to load `code`.
1560 pub fn load_c_str(&self, code: &CStr) -> Status {
1561 unsafe { Status::from_c_int_unchecked(
1562 luaL_loadstring(self.as_ptr(), code.as_ptr())
1563 ) }
1564 }
1565
1566 /// Create a new table and register there the functions in the list `library`.
1567 ///
1568 /// _Unlike_ this function's C counterpart, this will _not_ call
1569 /// [`Thread::check_version`].
1570 ///
1571 /// # Errors
1572 /// The underlying Lua state may raise a memory [error](crate::errors).
1573 pub fn new_lib<const N: usize>(&self, library: &Library<'_, N>) {
1574 unsafe {
1575 let l = self.as_ptr();
1576 lua_createtable(l, 0, N as _);
1577 luaL_setfuncs(l, library.as_ptr(), 0);
1578 }
1579 }
1580
1581 /// Create a new table with a size optimized to store all entries in
1582 /// `library`, but does not actually store them.
1583 ///
1584 /// This function is intended to be used in conjunction with
1585 /// [`Thread::set_funcs`].
1586 ///
1587 /// # Errors
1588 /// The underlying Lua state may raise a memory [error](crate::errors).
1589 pub fn new_lib_table<const N: usize>(&self, library: &Library<'_, N>) {
1590 let _ = library;
1591 unsafe { lua_createtable(self.as_ptr(), 0, N as _) }
1592 }
1593
1594 /// If the registry already doesn't have the key `table_name`, create a new
1595 /// table to be used as a metatable for userdata and return `true`.
1596 /// Otherwise, return `false`.
1597 ///
1598 /// In both cases, the function pushes onto the stack the final value
1599 /// associated with `table_name` in the registry.
1600 ///
1601 /// The function adds to this new table the pair `__name = table_name`,
1602 /// adds to the registry the pair `[table_name] = table`, and returns `true`.
1603 ///
1604 /// # Errors
1605 /// The underlying Lua state may raise a memory [error](crate::errors).
1606 pub fn new_metatable(&self, table_name: &CStr) -> bool {
1607 (unsafe { luaL_newmetatable(self.as_ptr(), table_name.as_ptr()) }) != 0
1608 }
1609
1610 /// If the function argument `arg` is an integer (or it is convertible to an
1611 /// integer), return this integer, or return `default`.
1612 ///
1613 /// # Errors
1614 /// The underlying Lua state may raise an [error](crate::errors) if the
1615 /// argument `arg` isn't a number, isn't a `nil` and not absent.
1616 pub fn opt_integer(&self, arg: c_int, default: Integer) -> Integer {
1617 unsafe { luaL_optinteger(self.as_ptr(), arg, default) }
1618 }
1619
1620 /// If the function argument `arg` is a string, return this string, or
1621 /// return `default`.
1622 ///
1623 /// This function works like [`Thread::opt_string`].
1624 ///
1625 /// # Errors
1626 /// The underlying Lua state may raise an [error](crate::errors) if the
1627 /// argument `arg` isn't a string, isn't a `nil` and not absent.
1628 pub fn opt_c_chars<'l>(
1629 &'l self, arg: c_int, default: &'l CStr
1630 ) -> &'l [c_char] {
1631 let mut len = 0;
1632 let str_ptr = unsafe { luaL_optlstring(
1633 self.as_ptr(), arg, default.as_ref().as_ptr(),
1634 &mut len as *mut _
1635 ) };
1636 unsafe { from_raw_parts(str_ptr, len) }
1637 }
1638
1639 /// If the function argument `arg` is a string, return this string, or
1640 /// return `default`.
1641 ///
1642 /// This function works like [`Thread::opt_string`].
1643 ///
1644 /// # Errors
1645 /// The underlying Lua state may raise an [error](crate::errors) if the
1646 /// argument `arg` isn't a string, isn't a `nil` and not absent.
1647 pub fn opt_c_str<'l>(&'l self, arg: c_int, default: &'l CStr) -> &'l CStr {
1648 unsafe { CStr::from_ptr(
1649 luaL_optstring(self.as_ptr(), arg, default.as_ptr())
1650 ) }
1651 }
1652
1653 /// If the function argument `arg` is a string, return this string, or
1654 /// return `default`.
1655 ///
1656 /// This function uses [`Thread::to_string`] to get its result, so all
1657 /// conversions and caveats of that function apply here.
1658 ///
1659 /// # Errors
1660 /// The underlying Lua state may raise an [error](crate::errors) if the
1661 /// argument `arg` isn't a string, isn't a `nil` and not absent.
1662 pub fn opt_string<'l>(&'l self, arg: c_int, default: &'l [u8]) -> &'l [u8] {
1663 let mut len = 0;
1664 let str_ptr = unsafe { luaL_optlstring(
1665 self.as_ptr(), arg, default.as_ptr() as *const _,
1666 &mut len as *mut _
1667 ) };
1668 unsafe { from_raw_parts(str_ptr as *const _, len) }
1669 }
1670
1671 /// If the function argument `arg` is a number, return this number as a
1672 /// [`Number`], or return `default`.
1673 ///
1674 /// # Errors
1675 /// The underlying Lua state may raise an [error](crate::errors) if the
1676 /// argument `arg` isn't a number, isn't a `nil` and not absent.
1677 pub fn opt_number(&self, arg: c_int, default: Number) -> Number {
1678 unsafe { luaL_optnumber(self.as_ptr(), arg, default) }
1679 }
1680
1681 /// Pushes the `fail` value onto the stack.
1682 pub fn push_fail(&self) {
1683 unsafe { luaL_pushfail(self.as_ptr()) }
1684 }
1685
1686 /// Create and return a reference, in the table at index `store_index`, for
1687 /// the object on the top of the stack (popping the object).
1688 ///
1689 /// A reference is a unique integer key.
1690 /// As long as you do not manually add integer keys into the table
1691 /// `store_index`, this function ensures the uniqueness of the key it
1692 /// returns.
1693 ///
1694 /// You can retrieve an object referred by the reference `ref_idx` by
1695 /// calling [`thread.raw_get_i(store_index, ref_idx)`](Thread::raw_get_i).
1696 /// See also [`Thread::destroy_ref`], which frees a reference.
1697 ///
1698 /// If the object on the top of the stack is nil, this returns the constant
1699 /// [`REF_NIL`].
1700 /// The constant [`NO_REF`] is guaranteed to be different from any reference
1701 /// returned.
1702 ///
1703 /// # Errors
1704 /// The underlying Lua state may raise a memory [error](crate::errors).
1705 pub fn create_ref(&self, store_index: c_int) -> c_int {
1706 unsafe { luaL_ref(self.as_ptr(), store_index) }
1707 }
1708
1709 /// Registers all functions in the list `library` into the table on the top
1710 /// of the stack (below optional upvalues).
1711 ///
1712 /// When `n_upvalues` is not zero, all functions are created with
1713 /// `n_upvalues` upvalues, initialized with copies of the values previously
1714 /// pushed on the stack on top of the library table.
1715 /// These values are popped from the stack after the registration.
1716 ///
1717 /// See also [`Library`].
1718 ///
1719 /// A value with a `None` value represents a placeholder, which is filled
1720 /// with `false`.
1721 ///
1722 /// # Errors
1723 /// The underlying Lua state may raise a memory [error](crate::errors).
1724 pub fn set_funcs<const N: usize>(&self, library: &Library<'_, N>, n_upvalues: u8) {
1725 unsafe { luaL_setfuncs(self.as_ptr(), library.as_ptr(), n_upvalues as _) }
1726 }
1727
1728 /// Set the metatable of the object on the top of the stack as the metatable
1729 /// associated with name `table_name` in the registry.
1730 ///
1731 /// See also [`Thread::new_metatable`].
1732 pub fn set_aux_metatable(&self, table_name: &CStr) {
1733 unsafe { luaL_setmetatable(self.as_ptr(), table_name.as_ptr()) }
1734 }
1735
1736 /// This function works like [`Thread::check_udata`], except that, when the
1737 /// test fails, it returns `None` instead of raising an error.
1738 ///
1739 /// # Safety
1740 /// The returned pointer must only be used while it's valid.
1741 ///
1742 /// While the metatable of userdata is protected from modification in the Lua standard library,
1743 /// an unsound implementation of setting the metatable of an object in Lua could change a userdatum's metatable
1744 /// and make the check for the `table_name` metatable unsound.
1745 pub unsafe fn test_udata(&self, arg: c_int, table_name: &CStr) -> Option<NonNull<c_void>> {
1746 NonNull::new(unsafe {luaL_testudata(self.as_ptr(), arg, table_name.as_ptr())})
1747 }
1748
1749 /// Create and push a traceback of the stack of thread `of`.
1750 ///
1751 /// If message is `Some`, it is appended at the beginning of the traceback.
1752 ///
1753 /// `level` tells at which level to start the traceback.
1754 ///
1755 /// # Errors
1756 /// The underlying Lua state may raise a memory [error](crate::errors).
1757 pub fn traceback(
1758 &self, of: &Self,
1759 message: Option<&CStr>,
1760 level: c_int
1761 ) {
1762 unsafe { luaL_traceback(
1763 self.as_ptr(), of.as_ptr(),
1764 message.map(|cstr| cstr.as_ptr()).unwrap_or(null()),
1765 level
1766 ) }
1767 }
1768
1769 /// Create and push a traceback of the stack of this thread to its own stack.
1770 ///
1771 /// This function works like [`Thread::traceback`].
1772 ///
1773 /// # Errors
1774 /// The underlying Lua state may raise a memory [error](crate::errors).
1775 pub fn traceback_self(&self, message: Option<&CStr>, level: c_int) {
1776 unsafe { luaL_traceback(
1777 self.as_ptr(), self.as_ptr(),
1778 message.map(|cstr| cstr.as_ptr()).unwrap_or(null()),
1779 level
1780 ) }
1781 }
1782
1783 /// Raise a type error for the argument `arg` of the C function that called
1784 /// it, using a standard message;
1785 /// `type_name` is a "name" for the expected type.
1786 ///
1787 /// This function never returns.
1788 pub fn type_error(&self, arg: c_int, type_name: &CStr) -> ! {
1789 unsafe { luaL_typeerror(self.as_ptr(), arg, type_name.as_ptr()) }
1790 }
1791
1792 /// Return the name of the type of the value at the given index.
1793 pub fn type_name_of(&self, index: c_int) -> &CStr {
1794 unsafe { CStr::from_ptr(luaL_typename(self.as_ptr(), index)) }
1795 }
1796
1797 /// Release the reference `ref_idx` from the table at index `store_index`.
1798 ///
1799 /// If `ref_idx` is [`NO_REF`] or [`REF_NIL`], this function does nothing.
1800 ///
1801 /// The entry is removed from the table, so that the referred object can be
1802 /// collected.
1803 /// The reference `ref_idx` is also freed to be used again.
1804 ///
1805 /// See also [`Thread::create_ref`].
1806 pub fn destroy_ref(&self, store_index: c_int, ref_idx: c_int) {
1807 unsafe { luaL_unref(self.as_ptr(), store_index, ref_idx) }
1808 }
1809
1810 /// Push onto the stack a string identifying the current position of the
1811 /// control at level `level` in the call stack.
1812 ///
1813 /// Typically, this string has the following format:
1814 ///
1815 /// `chunkname:currentline:`
1816 ///
1817 /// Level `0` is the running function, level `1` is the function that called
1818 /// the running function, etc.
1819 ///
1820 /// This function is used to build a prefix for error messages.
1821 ///
1822 /// # Errors
1823 /// The underlying Lua state may raise a memory [error](crate::errors).
1824 pub fn where_string(&self, level: c_int) {
1825 unsafe { luaL_where(self.as_ptr(), level) }
1826 }
1827}
1828
1829/// Utility type for operating on [`struct@Debug`] structures.
1830#[repr(transparent)]
1831pub struct ThreadDebug<'a, const ID_SIZE: usize> {
1832 thread: &'a Thread,
1833}
1834
1835impl<const ID_SIZE: usize> ThreadDebug<'_, ID_SIZE> {
1836 /// Return the current hook function.
1837 ///
1838 /// See also [`Hook`].
1839 pub fn hook_fn(&self) -> Hook<ID_SIZE> {
1840 let hook_fn = unsafe { lua_gethook(self.thread.as_ptr()) };
1841 unsafe { transmute(hook_fn) }
1842 }
1843
1844 /// Gets information about a specific function or function invocation.
1845 ///
1846 /// See also [`DebugWhat`](crate::dbg_what::DebugWhat) for generating `what`.
1847 pub fn get_info(&self, what: &CStr, ar: &mut Debug<ID_SIZE>) -> bool {
1848 (unsafe { lua_getinfo(self.thread.as_ptr(), what.as_ptr(), ar as *mut _ as *mut _) }) != 0
1849 }
1850
1851 /// Get information about a local variable or a temporary value of a given
1852 /// activation record or function.
1853 ///
1854 /// The function pushes the variable's value onto the stack and returns its
1855 /// name.
1856 /// It returns `None` (and pushes nothing) when the index is greater than
1857 /// the number of active local variables.
1858 ///
1859 /// # Activation records
1860 /// For activation records, the parameter `ar` must be a valid activation
1861 /// record that was filled by a previous call to [`ThreadDebug::get_stack`] or
1862 /// given as argument to a hook (see [`Hook`]).
1863 /// The index `n` selects which local variable to inspect.
1864 ///
1865 /// # Functions
1866 /// For functions, `ar` must be `None` and the function to be inspected must
1867 /// be on the top of the stack.
1868 /// In this case, only parameters of Lua functions are visible (as there is
1869 /// no information about what variables are active) and no values are pushed
1870 /// onto the stack.
1871 pub fn get_local<'dbg>(&self, ar: Option<&'dbg Debug<ID_SIZE>>, n: c_int) -> Option<&'dbg CStr> {
1872 let str_ptr = unsafe { lua_getlocal(
1873 self.thread.as_ptr(),
1874 ar.map(|ar| ar as *const _ as *const _).unwrap_or(null()),
1875 n
1876 ) };
1877
1878 if !str_ptr.is_null() {
1879 Some(unsafe { CStr::from_ptr(str_ptr) })
1880 } else {
1881 None
1882 }
1883 }
1884
1885 /// Set the debugging hook function.
1886 ///
1887 /// `hook` is the hook function.
1888 ///
1889 /// `mask` specifies on which events the hook will be called: it is formed
1890 /// by [`HookMask`].
1891 ///
1892 /// `count` is only meaningful when the mask includes the count hook
1893 /// (with [`HookMask::with_instructions`]).
1894 ///
1895 /// For each event, the hook is called as explained below:
1896 /// - The **call** hook is called when the interpreter calls a function.
1897 /// The hook is called just after Lua enters the new function.
1898 /// - The **return** hook is called when the interpreter returns from a function.
1899 /// The hook is called just before Lua leaves the function.
1900 /// - The **line** hook is called when the interpreter is about to start the execution of a new line of code,
1901 /// or when it jumps back in the code (even to the same line).
1902 /// This event only happens while Lua is executing a Lua function.
1903 /// - The **count** hook is called after the interpreter executes every `count` instructions.
1904 /// This event only happens while Lua is executing a Lua function.
1905 ///
1906 /// Hooks are disabled by supplying an empty `mask`.
1907 pub fn set_hook_fn(&self, hook_fn: Hook<ID_SIZE>, mask: HookMask, count: c_int) {
1908 let hook_fn = unsafe { transmute::<Hook<ID_SIZE>, Hook<DEFAULT_ID_SIZE>>(hook_fn) };
1909 unsafe { lua_sethook(self.thread.as_ptr(), hook_fn, mask.into_c_int(), count) }
1910 }
1911
1912 /// Get information about the interpreter runtime stack.
1913 ///
1914 /// This function fills parts of a [`struct@Debug`] structure with an
1915 /// identification of the activation record of the function executing at a
1916 /// given level.
1917 ///
1918 /// Level `0` is the current running function, whereas level `n + 1` is the
1919 /// function that has called level `n` (except for tail calls, which do not
1920 /// count in the stack).
1921 /// When called with a level greater than the stack depth, this function
1922 /// returns `None`.
1923 pub fn get_stack(&self, level: c_int) -> Option<Debug<ID_SIZE>> {
1924 let mut ar = Debug::<ID_SIZE>::zeroed();
1925 if unsafe { lua_getstack(self.thread.as_ptr(), level, &mut ar as *mut _ as *mut _) } != 0 {
1926 Some(ar)
1927 } else {
1928 None
1929 }
1930 }
1931
1932 /// Set the value of a local variable of a given activation record and
1933 /// return its name.
1934 ///
1935 /// Returns `None` (and pops nothing) when the index is greater than the
1936 /// number of active local variables.
1937 ///
1938 /// This function assigns the value on the top of the stack to the variable.
1939 /// It also pops the value from the stack.
1940 pub fn set_local<'dbg>(&self, ar: &'dbg Debug<ID_SIZE>, n: c_int) -> Option<&'dbg CStr> {
1941 let str_ptr = unsafe { lua_setlocal(self.thread.as_ptr(), ar as *const _ as *const _, n) };
1942 if !str_ptr.is_null() {
1943 Some(unsafe { CStr::from_ptr(str_ptr) })
1944 } else {
1945 None
1946 }
1947 }
1948}