Struct Coroutine

Source
pub struct Coroutine<'l> { /* private fields */ }
Expand description

Data structure that represents a Lua coroutine.

See also Lua for the main thread.

This type does not have a Drop implementation. Any threads that are not used anymore must either be closed manually with Coroutine::close or left to be garbage-collected by Lua.

Implementations§

Source§

impl<'l> Coroutine<'l>

Source

pub const fn new(thread: &'l mut Thread) -> Self

Wrap a Lua Thread as if it is a coroutine.

Source§

impl Coroutine<'_>

Source

pub fn close(&mut self) -> Status

Source

pub fn close_from(&mut self, from: &Self) -> Status

Methods from Deref<Target = Thread>§

Source

pub fn as_ptr(&self) -> *mut State

Return the raw C pointer that represents the underlying Lua state.

Source

pub fn run_managed<R>(&mut self, func: impl FnOnce(Managed<'_>) -> R) -> R

Run code that can restart the GC and potentially invalidate pointers in a context.

Examples found in repository?
examples/interpreter.rs (line 27)
22fn report(lua: &mut LuaThread, status: LuaStatus) -> bool {
23	if !status.is_ok() {
24		if let Some(message) = lua.to_c_str(-1) {
25			c_eprintln(message);
26		}
27		lua.run_managed(|mut mg| unsafe { mg.pop(1) });
28		false
29	} else {
30		true
31	}
32}
33
34unsafe extern "C-unwind" fn l_err_handler(l: *mut LuaState) -> c_int {
35	let lua = unsafe { LuaThread::from_ptr_mut(l) };
36
37	if let Some(msg) = lua.to_c_str(1) {
38		lua.traceback(lua, Some(msg), 1);
39		return 1
40	}
41
42	let ok = lua.run_managed(|mut mg| unsafe {
43		mg.call_metamethod(1, c"__tostring")
44	});
45
46	if ok && lua.type_of(-1) == LuaType::String {
47		return 1
48	}
49
50	unsafe { lua_push_fmt_string!(lua, c"(error object is a %s value)", lua.type_name_of(1)) };
51
52	1
53}
54
55unsafe extern "C-unwind" fn l_main(l: *mut LuaState) -> c_int {
56	let lua = unsafe { LuaThread::from_ptr_mut(l) };
57
58	lua.check_version();
59	lua.run_managed(|mut mg| mg.open_libs());
60
61	lua.push_c_function(l_err_handler);
62	let base = lua.top();
63
64	let mut arguments = args().skip(1);
65	let load_status = if let Some(mut file_name) = arguments.next() {
66		lua.load_file(unsafe {
67			file_name.push('\0');
68			CStr::from_bytes_until_nul(file_name.as_bytes()).unwrap_unchecked()
69		})
70	} else {
71		lua.load_stdin()
72	};
73
74	if !report(lua, load_status) {
75		return 0
76	}
77
78	let mut arg_count: c_uint = 0;
79	for arg in arguments {
80		lua.push_string(arg.as_bytes());
81		arg_count += 1;
82	}
83
84	let run_status = lua.run_managed(|mut mg| {
85		mg.restart_gc();
86		let run_status = unsafe { mg.pcall(arg_count, 0, base) };
87		mg.stop_gc();
88		run_status
89	});
90	if !report(lua, run_status) {
91		return 0
92	}
93
94	lua.push_boolean(true);
95	1
96}
97
98fn main() -> ExitCode {
99	let mut lua = Lua::new();
100
101	lua.push_c_function(l_main);
102	let status = lua.run_managed(|mut mg| unsafe { mg.pcall(0, 1, 0) });
103	let is_ok = lua.to_boolean(-1);
104	report(&mut lua, status);
105
106	if status.is_ok() && is_ok {
107		ExitCode::SUCCESS
108	} else {
109		ExitCode::FAILURE
110	}
111}
More examples
Hide additional examples
examples/string_enum.rs (lines 58-62)
55unsafe extern "C-unwind" fn l_main(l: *mut LuaState) -> c_int {
56	let lua = unsafe { LuaThread::from_ptr_mut(l) };
57	let mut test = move |variant: &[u8]| {
58		lua.run_managed(move |mut mg| {
59			mg.push_c_function(l_test);
60			mg.push_string(variant);
61			unsafe { mg.call(1, 0) }
62		})
63	};
64	test(b"udp");
65	test(b"tcp");
66	test(b"unix udp");
67	test(b"unix tcp");
68	test(b"invalid");
69	0
70}
71
72fn main() {
73	let mut lua = Lua::new();
74	let did_run_ok = lua.run_managed(move |mut mg| {
75		mg.push_c_function(l_main);
76		unsafe { mg.pcall(0, 1, 0).is_ok() }
77	});
78	assert!(!did_run_ok, "test code should fail");
79}
examples/push_trait.rs (line 65)
63fn main() {
64	let mut lua = Lua::new();
65	lua.run_managed(|mut mg| mg.open_libs());
66
67	if !lua.load_string(PRINT_CODE.as_bytes(), PRINT_CODE_LUA_NAME).is_ok() {
68		panic!("couldn't load Lua chunk");
69	}
70
71	lua.push(4 as LuaInteger);
72	lua.push(3.1 as LuaNumber);
73	lua.push("how");
74
75	if !lua.run_managed(|mut mg| {
76		mg.restart_gc();
77		unsafe { mg.pcall(3, 0, 0) }
78	}).is_ok() {
79		let error_bytes = lua.to_string(-1);
80		panic!(
81			"error while running Lua chunk: {}",
82			error_bytes.map(String::from_utf8_lossy)
83				.unwrap_or(std::borrow::Cow::Borrowed("<no message>"))
84		);
85	}
86}
examples/hello.rs (line 8)
6unsafe extern "C-unwind" fn l_main(l: *mut LuaState) -> c_int {
7	let lua = unsafe { LuaThread::from_ptr_mut(l) };
8	lua.run_managed(move |mut mg| mg.open_libs());
9
10	let is_ok = lua.load_string(
11		r#"print("Hello, world!")"#,
12		c"=<embedded>"
13	).is_ok();
14	if !is_ok {
15		let error = {
16			lua.to_string(-1)
17				.and_then(move |bytes| core::str::from_utf8(bytes).ok())
18				.unwrap_or("<message is not UTF-8>")
19		};
20		eprintln!("couldn't load example Lua code:\n\t{error}");
21		lua.push_boolean(false);
22		return 1
23	}
24
25	let is_ok = lua.run_managed(move |mut mg| unsafe { mg.pcall(0, 0, 0).is_ok() });
26	if !is_ok {
27		let error = {
28			lua.to_string(-1)
29				.and_then(move |bytes| core::str::from_utf8(bytes).ok())
30				.unwrap_or("<message is not UTF-8>")
31		};
32		eprintln!("couldn't run example Lua code:\n\t{error}");
33		lua.push_boolean(false);
34		return 1
35	}
36
37	lua.push_boolean(true);
38	1
39}
40
41fn main() {
42	let mut lua = Lua::new();
43
44	let did_run_ok = lua.run_managed(move |mut mg| {
45		mg.push_c_function(l_main);
46		if unsafe { mg.pcall(0, 1, 0).is_ok() } {
47			mg.to_boolean(-1)
48		} else {
49			false
50		}
51	});
52	if !did_run_ok {
53		panic!("couldn't run \"Hello, world!\" example for some reason");
54	}
55}
examples/os2.rs (lines 25-49)
11unsafe extern "C-unwind" fn l_metadata(l: *mut LuaState) -> c_int {	
12	let lua = unsafe { LuaThread::from_ptr_mut(l) };
13	let path = lua.check_string(1);
14	
15	let meta = match metadata(String::from_utf8_lossy(path).into_owned()) {
16		Ok(meta) => meta,
17		Err(error) => {
18			lua.push_fail();
19			let mut buf = lua.new_buffer();
20			let _ = write!(buf, "{error}");
21			return 2
22		}
23	};
24
25	lua.run_managed(|mut mg| {
26		mg.create_table(0, 1);
27
28		let file_type = meta.file_type();
29		mg.push_string(if file_type.is_file() {
30			"file"
31		} else if file_type.is_dir() {
32			"directory"
33		} else if file_type.is_symlink() {
34			"symlink"
35		} else {
36			"other"
37		}.as_bytes());
38		mg.set_field(-2, c"type");
39
40		mg.push_integer(meta.len() as _);
41		mg.set_field(-2, c"len");
42
43		if let Ok(time) = meta.modified() {
44			if let Ok(time) = time.duration_since(SystemTime::UNIX_EPOCH) {
45				mg.push_number(time.as_secs_f64());
46				mg.set_field(-2, c"modified");
47			}
48		}
49	});
50
51	1
52}
Source

pub unsafe fn run_managed_no_gc<R>( &self, func: impl FnOnce(Managed<'_>) -> R, ) -> R

This is the same as Thread::run_managed, however it doesn’t borrow mutably by assuming that the garbage collector will not collect (and thus invalidate) any outside references.

§Safety

The body of func must not include any operations that may cause the garbage collector to run a cycle.

For example, if performing arithmetic on numbers does not trigger any metamethods, or it triggers metamethods that can’t ever cause the collector to collect, then this invariant is not broken.

Source

pub unsafe fn close_as_main(&mut self)

Close all active to-be-closed variables in the main thread, release all objects (calling the corresponding garbage-collection metamethods, if any), and free all dynamic memory used by this Thread.

§Safety

This Thread must not be used for any further API calls, as the underlying Lua pointer becomes invalid after this call.

Source

pub fn close_as_coroutine(&mut self) -> Status

Reset a thread, cleaning its call stack and closing all pending to-be-closed variables.

Returns a status code: Status::Ok for no errors in the thread (either the original error that stopped the thread or errors in closing methods), or an error status otherwise.

In case of error, leaves the error object on the top of its own stack.

Source

pub fn close_as_coroutine_from(&mut self, from: &Self) -> Status

This behaves similarly to Thread::close_as_coroutine, but allows to specify from, which represents the coroutine that is resetting this one.

Source

pub fn at_panic(&self, func: Option<CFunction>) -> Option<CFunction>

Set a new panic function and return the old one.

Source

pub fn error(&self) -> !

Raise a Lua error, using the value on the top of the stack as the error object.

This function does a long jump, and therefore never returns.

Source

pub fn restart_gc(&self)

Restart the garbage collector.

This by itself does not run a collection.

Examples found in repository?
examples/push_trait.rs (line 76)
63fn main() {
64	let mut lua = Lua::new();
65	lua.run_managed(|mut mg| mg.open_libs());
66
67	if !lua.load_string(PRINT_CODE.as_bytes(), PRINT_CODE_LUA_NAME).is_ok() {
68		panic!("couldn't load Lua chunk");
69	}
70
71	lua.push(4 as LuaInteger);
72	lua.push(3.1 as LuaNumber);
73	lua.push("how");
74
75	if !lua.run_managed(|mut mg| {
76		mg.restart_gc();
77		unsafe { mg.pcall(3, 0, 0) }
78	}).is_ok() {
79		let error_bytes = lua.to_string(-1);
80		panic!(
81			"error while running Lua chunk: {}",
82			error_bytes.map(String::from_utf8_lossy)
83				.unwrap_or(std::borrow::Cow::Borrowed("<no message>"))
84		);
85	}
86}
More examples
Hide additional examples
examples/interpreter.rs (line 85)
55unsafe extern "C-unwind" fn l_main(l: *mut LuaState) -> c_int {
56	let lua = unsafe { LuaThread::from_ptr_mut(l) };
57
58	lua.check_version();
59	lua.run_managed(|mut mg| mg.open_libs());
60
61	lua.push_c_function(l_err_handler);
62	let base = lua.top();
63
64	let mut arguments = args().skip(1);
65	let load_status = if let Some(mut file_name) = arguments.next() {
66		lua.load_file(unsafe {
67			file_name.push('\0');
68			CStr::from_bytes_until_nul(file_name.as_bytes()).unwrap_unchecked()
69		})
70	} else {
71		lua.load_stdin()
72	};
73
74	if !report(lua, load_status) {
75		return 0
76	}
77
78	let mut arg_count: c_uint = 0;
79	for arg in arguments {
80		lua.push_string(arg.as_bytes());
81		arg_count += 1;
82	}
83
84	let run_status = lua.run_managed(|mut mg| {
85		mg.restart_gc();
86		let run_status = unsafe { mg.pcall(arg_count, 0, base) };
87		mg.stop_gc();
88		run_status
89	});
90	if !report(lua, run_status) {
91		return 0
92	}
93
94	lua.push_boolean(true);
95	1
96}
Source

pub fn stop_gc(&self)

Stop the garbage collector.

Examples found in repository?
examples/interpreter.rs (line 87)
55unsafe extern "C-unwind" fn l_main(l: *mut LuaState) -> c_int {
56	let lua = unsafe { LuaThread::from_ptr_mut(l) };
57
58	lua.check_version();
59	lua.run_managed(|mut mg| mg.open_libs());
60
61	lua.push_c_function(l_err_handler);
62	let base = lua.top();
63
64	let mut arguments = args().skip(1);
65	let load_status = if let Some(mut file_name) = arguments.next() {
66		lua.load_file(unsafe {
67			file_name.push('\0');
68			CStr::from_bytes_until_nul(file_name.as_bytes()).unwrap_unchecked()
69		})
70	} else {
71		lua.load_stdin()
72	};
73
74	if !report(lua, load_status) {
75		return 0
76	}
77
78	let mut arg_count: c_uint = 0;
79	for arg in arguments {
80		lua.push_string(arg.as_bytes());
81		arg_count += 1;
82	}
83
84	let run_status = lua.run_managed(|mut mg| {
85		mg.restart_gc();
86		let run_status = unsafe { mg.pcall(arg_count, 0, base) };
87		mg.stop_gc();
88		run_status
89	});
90	if !report(lua, run_status) {
91		return 0
92	}
93
94	lua.push_boolean(true);
95	1
96}
Source

pub fn mem_kbytes(&self) -> c_uint

Return the current amount of memory (in kilobytes) in use by this Thread.

Source

pub fn mem_byte_remainder(&self) -> c_uint

Return the remainder of dividing the current amount of bytes of memory in use by this Thread by 1024.

Source

pub fn is_gc_running(&self) -> bool

Return true if the collector is running (i.e. not stopped).

Source

pub fn switch_gc_to(&mut self, gc: GcMode)

Change the collector to either incremental or generational mode (see also GcMode) with the given parameters.

Source

pub fn abs_index(&self, idx: c_int) -> c_int

Convert the acceptable index idx into an equivalent absolute index (that is, one that does not depend on the stack size).

Source

pub fn test_stack(&self, n: c_uint) -> bool

Ensure that the stack has space for at least n extra elements. That is, that you can safely push up to n values into it.

Returns false if it cannot fulfill the request, either because it would cause the stack to be greater than a fixed maximum size (typically at least several thousand elements) or because it cannot allocate memory for the extra space.

This function never shrinks the stack; if the stack already has space for the extra elements, it is left unchanged.

Source

pub fn copy(&self, from_idx: c_int, to_idx: c_int)

Copy the element at from_idx into the valid index to_idx, replacing the value at that position.

Values at other positions are not affected.

Source

pub fn create_table(&self, n_arr: c_uint, n_rec: c_uint)

Create a new empty table and push it onto the stack.

narr is a hint for how many elements the table will have as a sequence, and nrec is a hint for how many other elements the table will have. Lua may use these hints to preallocate memory for the new table. This preallocation may help performance when its known in advance how many elements the table will have.

See also Thread::new_table.

§Errors

The underlying Lua state may raise a memory error.

Examples found in repository?
examples/os2.rs (line 26)
11unsafe extern "C-unwind" fn l_metadata(l: *mut LuaState) -> c_int {	
12	let lua = unsafe { LuaThread::from_ptr_mut(l) };
13	let path = lua.check_string(1);
14	
15	let meta = match metadata(String::from_utf8_lossy(path).into_owned()) {
16		Ok(meta) => meta,
17		Err(error) => {
18			lua.push_fail();
19			let mut buf = lua.new_buffer();
20			let _ = write!(buf, "{error}");
21			return 2
22		}
23	};
24
25	lua.run_managed(|mut mg| {
26		mg.create_table(0, 1);
27
28		let file_type = meta.file_type();
29		mg.push_string(if file_type.is_file() {
30			"file"
31		} else if file_type.is_dir() {
32			"directory"
33		} else if file_type.is_symlink() {
34			"symlink"
35		} else {
36			"other"
37		}.as_bytes());
38		mg.set_field(-2, c"type");
39
40		mg.push_integer(meta.len() as _);
41		mg.set_field(-2, c"len");
42
43		if let Ok(time) = meta.modified() {
44			if let Ok(time) = time.duration_since(SystemTime::UNIX_EPOCH) {
45				mg.push_number(time.as_secs_f64());
46				mg.set_field(-2, c"modified");
47			}
48		}
49	});
50
51	1
52}
Source

pub unsafe fn dump( &self, writer: Writer, writer_data: *mut c_void, strip_debug_info: bool, ) -> c_int

Dump a function as a binary chunk, and return the status of the operation.

This function receives a Lua function on the top of the stack and produces a binary chunk that, if loaded again, results in a function equivalent to the one dumped.

As it produces parts of the chunk, the function calls writer (see also Writer) with the given data to write them. If strip_debug_info is true, the binary representation may not include all debug information about the function, to save space.

The value returned is the error code returned by the last call to the writer.

This function does not pop the Lua function from the stack.

§Safety

writer_data must be valid to be passed to writer.

Source

pub fn get_alloc_fn(&self) -> (Alloc, *mut c_void)

Return the memory-allocation function of this Thread along with the opaque pointer given when the memory-allocator function was set.

Source

pub fn get_global(&self, name: &CStr) -> Type

Push onto the stack the value of the global name, and return the type of that value.

§Errors

The underlying Lua state may raise an arbitrary error.

Source

pub fn get_i_uservalue(&self, ud_index: c_int, n: c_int) -> Type

Push onto the stack the n-th user value associated with the full userdata at the given index and returns the type of the pushed value.

If the userdata does not have that value, push nil and return Type::None.

Source

pub fn get_metatable(&self, obj_index: c_int) -> bool

If the value at the given index has a metatable, push that metatable onto the stack and return true. Otherwise, push nothing and return false.

Source

pub fn top(&self) -> c_int

Return the index of the top element in the stack.

Because indices start at 1, this result is equal to the number of elements in the stack; in particular, 0 means an empty stack.

Examples found in repository?
examples/interpreter.rs (line 62)
55unsafe extern "C-unwind" fn l_main(l: *mut LuaState) -> c_int {
56	let lua = unsafe { LuaThread::from_ptr_mut(l) };
57
58	lua.check_version();
59	lua.run_managed(|mut mg| mg.open_libs());
60
61	lua.push_c_function(l_err_handler);
62	let base = lua.top();
63
64	let mut arguments = args().skip(1);
65	let load_status = if let Some(mut file_name) = arguments.next() {
66		lua.load_file(unsafe {
67			file_name.push('\0');
68			CStr::from_bytes_until_nul(file_name.as_bytes()).unwrap_unchecked()
69		})
70	} else {
71		lua.load_stdin()
72	};
73
74	if !report(lua, load_status) {
75		return 0
76	}
77
78	let mut arg_count: c_uint = 0;
79	for arg in arguments {
80		lua.push_string(arg.as_bytes());
81		arg_count += 1;
82	}
83
84	let run_status = lua.run_managed(|mut mg| {
85		mg.restart_gc();
86		let run_status = unsafe { mg.pcall(arg_count, 0, base) };
87		mg.stop_gc();
88		run_status
89	});
90	if !report(lua, run_status) {
91		return 0
92	}
93
94	lua.push_boolean(true);
95	1
96}
Source

pub fn insert(&self, index: c_int)

Move the top element into the given valid index, shifting up the elements above that index to open space.

This function cannot be called with a pseudo-index, because a pseudo-index is not an actual stack position.

Source

pub fn is_boolean(&self, index: c_int) -> bool

Return true if the value at the given index is a boolean.

Source

pub fn is_c_function(&self, index: c_int) -> bool

Return true if the value at the given index is a C function.

Source

pub fn is_function(&self, index: c_int) -> bool

Return true if the value at the given index is a function (either C or Lua).

Source

pub fn is_integer(&self, index: c_int) -> bool

Return true if the value at the given index is an integer.

Source

pub fn is_light_userdata(&self, index: c_int) -> bool

Return true if the value at the given index is a light userdata.

Source

pub fn is_nil(&self, index: c_int) -> bool

Return true if the value at the given index is nil.

Source

pub fn is_none(&self, index: c_int) -> bool

Return true if the value at the given index is not valid.

Source

pub fn is_none_or_nil(&self, index: c_int) -> bool

Return true if the value at the given index is not valid or is nil.

Source

pub fn is_number(&self, index: c_int) -> bool

Return true if the value at the given index is a number.

Source

pub fn is_string(&self, index: c_int) -> bool

Return true if the value at the given index is a string or a number, which is always convertible to a string.

Source

pub fn is_table(&self, index: c_int) -> bool

Return true if the value at the given index is a table.

Source

pub fn is_thread(&self, index: c_int) -> bool

Return true if the value at the given index is a thread.

Source

pub fn is_userdata(&self, index: c_int) -> bool

Return true if the value at the given index is a userdata (either full or light).

Source

pub fn can_yield(&self) -> bool

Return true if the coroutine can yield.

Source

pub unsafe fn load( &self, reader: Reader, reader_data: *mut c_void, chunk_name: &CStr, mode: Option<&CStr>, ) -> Status

Load a Lua chunk without running it.

If there are no errors, push the compiled chunk as a Lua function. Otherwise, push an error message.

This function uses a user-supplied reader to read the chunk (see also Reader). reader_data is an opaque value passed to the reader function.

chunk_name gives a name to the chunk, which is used for error messages and in debug information.

The function automatically detects whether the chunk is text or binary and loads it accordingly. The string mode works similarly as in the Lua base library function load:

  • Some("b") loads only binary chunks.
  • Some("t") loads only text chunks.
  • Some("bt") loads both binary and text chunks.
  • None is equivalent to the string "bt".

This function uses the stack internally, so reader must always leave the stack unmodified when returning.

If the resulting function has upvalues, its first upvalue is set to the value of the global environment stored at index REGISTRY_GLOBALS in the registry. When loading main chunks, this upvalue will be the _ENV variable. Other upvalues are initialized with nil.

§Safety

reader_data must be valid to be passed to reader.

Source

pub fn new_table(&self)

Create a new empty table and push it onto the stack.

See also Thread::create_table.

§Errors

The underlying Lua state may raise a memory error.

Source

pub fn new_thread(&self) -> Coroutine<'_>

Create a new thread, push it on the stack, and return a Coroutine that represents this new thread.

The new thread returned by this function shares with the original thread its global environment, but has an independent execution stack. Threads are subject to garbage collection, like any Lua object.

§Errors

The underlying Lua state may raise a memory error.

Source

pub unsafe fn new_userdata_raw( &self, size: usize, n_uservalues: c_int, ) -> *mut c_void

Create and push on the stack a new full userdata, with n_uservalues associated Lua values, called user values, and an associated block of raw memory of size bytes.

The function returns a pointer to the block of memory that was allocated by Lua.

The user values can be set and read with the functions Thread::set_i_uservalue and Thread::get_i_uservalue.

You may use this function if, for instance, the layout of the data in the allocation changes based on run-time information.

§Errors

The underlying Lua state may raise a memory error.

§Safety

Lua ensures that the pointer is valid as long as the corresponding userdata is alive. Moreover, if the userdata is marked for finalization, it is valid at least until the call to its finalizer. The returned pointer must only be used while it’s valid.

Lua makes no guarantees about the alignment of the pointer. It depends entirely on the allocator function used.

Source

pub fn next(&self, index: c_int) -> bool

Pop a key from the stack, and push a key–value pair from the table at the given index, the “next” pair after the given key.

This function returns true while there are still elements to go through. If there are no more elements in the table, then this it returns false and pushes nothing.

§Note on string conversion functions

While traversing a table, avoid calling Thread::to_c_chars directly on a key, unless it is known that the key is actually a string. Thread::to_c_chars and other similar functions may change the value at the given index; this confuses the next call to Thread::next.

§Errors

The underlying Lua state may raise an error if a given key is neither nil nor present in the table.

Source

pub fn push_boolean(&self, value: bool)

Push a bool onto the stack.

Examples found in repository?
examples/hello.rs (line 21)
6unsafe extern "C-unwind" fn l_main(l: *mut LuaState) -> c_int {
7	let lua = unsafe { LuaThread::from_ptr_mut(l) };
8	lua.run_managed(move |mut mg| mg.open_libs());
9
10	let is_ok = lua.load_string(
11		r#"print("Hello, world!")"#,
12		c"=<embedded>"
13	).is_ok();
14	if !is_ok {
15		let error = {
16			lua.to_string(-1)
17				.and_then(move |bytes| core::str::from_utf8(bytes).ok())
18				.unwrap_or("<message is not UTF-8>")
19		};
20		eprintln!("couldn't load example Lua code:\n\t{error}");
21		lua.push_boolean(false);
22		return 1
23	}
24
25	let is_ok = lua.run_managed(move |mut mg| unsafe { mg.pcall(0, 0, 0).is_ok() });
26	if !is_ok {
27		let error = {
28			lua.to_string(-1)
29				.and_then(move |bytes| core::str::from_utf8(bytes).ok())
30				.unwrap_or("<message is not UTF-8>")
31		};
32		eprintln!("couldn't run example Lua code:\n\t{error}");
33		lua.push_boolean(false);
34		return 1
35	}
36
37	lua.push_boolean(true);
38	1
39}
More examples
Hide additional examples
examples/interpreter.rs (line 94)
55unsafe extern "C-unwind" fn l_main(l: *mut LuaState) -> c_int {
56	let lua = unsafe { LuaThread::from_ptr_mut(l) };
57
58	lua.check_version();
59	lua.run_managed(|mut mg| mg.open_libs());
60
61	lua.push_c_function(l_err_handler);
62	let base = lua.top();
63
64	let mut arguments = args().skip(1);
65	let load_status = if let Some(mut file_name) = arguments.next() {
66		lua.load_file(unsafe {
67			file_name.push('\0');
68			CStr::from_bytes_until_nul(file_name.as_bytes()).unwrap_unchecked()
69		})
70	} else {
71		lua.load_stdin()
72	};
73
74	if !report(lua, load_status) {
75		return 0
76	}
77
78	let mut arg_count: c_uint = 0;
79	for arg in arguments {
80		lua.push_string(arg.as_bytes());
81		arg_count += 1;
82	}
83
84	let run_status = lua.run_managed(|mut mg| {
85		mg.restart_gc();
86		let run_status = unsafe { mg.pcall(arg_count, 0, base) };
87		mg.stop_gc();
88		run_status
89	});
90	if !report(lua, run_status) {
91		return 0
92	}
93
94	lua.push_boolean(true);
95	1
96}
Source

pub fn push_c_closure(&self, func: CFunction, n_upvalues: c_int)

Push a new C closure onto the stack.

This function receives a C function func and pushes onto the stack a Lua value of type function that, when called, invokes the corresponding C function. n_upvalues tells how many upvalues this function will have.

Any function to be callable by Lua must follow the correct protocol to receive its parameters and return its results (see CFunction).

§C closures

When a C function is created, it is possible to associate some values with it, which are called upvalues. These upvalues are then accessible to the function whenever it is called, where the function is called a C closure. To create a C closure:

  1. Push the initial values for its upvalues onto the stack. (When there are multiple upvalues, the first value is pushed first.)
  2. Call this function with the argument n_upvalues telling how many upvalues will be associated with the function. The function will also pop these values from the stack.

When n_upvalues == 0, this function creates a “light” C function, which is just a pointer to the C function. In that case, it never raises a memory error.

See also Thread::push_c_function.

§Errors

The underlying Lua state may raise a memory error if n_upvalues > 0.

Source

pub fn push_c_function(&self, func: CFunction)

Push a light C function onto the stack (that is, a C function with no upvalues).

See also Thread::push_c_closure.

Examples found in repository?
examples/hello.rs (line 45)
41fn main() {
42	let mut lua = Lua::new();
43
44	let did_run_ok = lua.run_managed(move |mut mg| {
45		mg.push_c_function(l_main);
46		if unsafe { mg.pcall(0, 1, 0).is_ok() } {
47			mg.to_boolean(-1)
48		} else {
49			false
50		}
51	});
52	if !did_run_ok {
53		panic!("couldn't run \"Hello, world!\" example for some reason");
54	}
55}
More examples
Hide additional examples
examples/string_enum.rs (line 59)
55unsafe extern "C-unwind" fn l_main(l: *mut LuaState) -> c_int {
56	let lua = unsafe { LuaThread::from_ptr_mut(l) };
57	let mut test = move |variant: &[u8]| {
58		lua.run_managed(move |mut mg| {
59			mg.push_c_function(l_test);
60			mg.push_string(variant);
61			unsafe { mg.call(1, 0) }
62		})
63	};
64	test(b"udp");
65	test(b"tcp");
66	test(b"unix udp");
67	test(b"unix tcp");
68	test(b"invalid");
69	0
70}
71
72fn main() {
73	let mut lua = Lua::new();
74	let did_run_ok = lua.run_managed(move |mut mg| {
75		mg.push_c_function(l_main);
76		unsafe { mg.pcall(0, 1, 0).is_ok() }
77	});
78	assert!(!did_run_ok, "test code should fail");
79}
examples/interpreter.rs (line 61)
55unsafe extern "C-unwind" fn l_main(l: *mut LuaState) -> c_int {
56	let lua = unsafe { LuaThread::from_ptr_mut(l) };
57
58	lua.check_version();
59	lua.run_managed(|mut mg| mg.open_libs());
60
61	lua.push_c_function(l_err_handler);
62	let base = lua.top();
63
64	let mut arguments = args().skip(1);
65	let load_status = if let Some(mut file_name) = arguments.next() {
66		lua.load_file(unsafe {
67			file_name.push('\0');
68			CStr::from_bytes_until_nul(file_name.as_bytes()).unwrap_unchecked()
69		})
70	} else {
71		lua.load_stdin()
72	};
73
74	if !report(lua, load_status) {
75		return 0
76	}
77
78	let mut arg_count: c_uint = 0;
79	for arg in arguments {
80		lua.push_string(arg.as_bytes());
81		arg_count += 1;
82	}
83
84	let run_status = lua.run_managed(|mut mg| {
85		mg.restart_gc();
86		let run_status = unsafe { mg.pcall(arg_count, 0, base) };
87		mg.stop_gc();
88		run_status
89	});
90	if !report(lua, run_status) {
91		return 0
92	}
93
94	lua.push_boolean(true);
95	1
96}
97
98fn main() -> ExitCode {
99	let mut lua = Lua::new();
100
101	lua.push_c_function(l_main);
102	let status = lua.run_managed(|mut mg| unsafe { mg.pcall(0, 1, 0) });
103	let is_ok = lua.to_boolean(-1);
104	report(&mut lua, status);
105
106	if status.is_ok() && is_ok {
107		ExitCode::SUCCESS
108	} else {
109		ExitCode::FAILURE
110	}
111}
Source

pub fn push_global_table(&self)

Push the global environment onto the stack.

Source

pub fn push_integer(&self, value: Integer)

Push an Integer onto the stack.

Examples found in repository?
examples/push_trait.rs (line 22)
21	fn push_into(&self, thread: &LuaThread) {
22		thread.push_integer(*self);
23	}
More examples
Hide additional examples
examples/os2.rs (line 40)
11unsafe extern "C-unwind" fn l_metadata(l: *mut LuaState) -> c_int {	
12	let lua = unsafe { LuaThread::from_ptr_mut(l) };
13	let path = lua.check_string(1);
14	
15	let meta = match metadata(String::from_utf8_lossy(path).into_owned()) {
16		Ok(meta) => meta,
17		Err(error) => {
18			lua.push_fail();
19			let mut buf = lua.new_buffer();
20			let _ = write!(buf, "{error}");
21			return 2
22		}
23	};
24
25	lua.run_managed(|mut mg| {
26		mg.create_table(0, 1);
27
28		let file_type = meta.file_type();
29		mg.push_string(if file_type.is_file() {
30			"file"
31		} else if file_type.is_dir() {
32			"directory"
33		} else if file_type.is_symlink() {
34			"symlink"
35		} else {
36			"other"
37		}.as_bytes());
38		mg.set_field(-2, c"type");
39
40		mg.push_integer(meta.len() as _);
41		mg.set_field(-2, c"len");
42
43		if let Ok(time) = meta.modified() {
44			if let Ok(time) = time.duration_since(SystemTime::UNIX_EPOCH) {
45				mg.push_number(time.as_secs_f64());
46				mg.set_field(-2, c"modified");
47			}
48		}
49	});
50
51	1
52}
Source

pub unsafe fn push_light_userdata(&self, ptr: *mut c_void)

Push a light userdata onto the stack.

A light userdata represents a plain pointer. It is a value, like a number: it is not created, it has no individual metatable, and it is not collected (as it was never created).

A light userdata is equal to any light userdata with the same C address.

§Safety

ptr can be used arbitrarily in Lua, so this method should only be used for trusted code.

Source

pub fn push_c_chars<'l>(&'l self, data: &[c_char]) -> &'l [c_char]

Works the same as Thread::push_string, however it accepts c_chars instead of u8s.

§Errors

The underlying Lua state may raise a memory error.

Source

pub fn push_string(&self, data: impl AsRef<[u8]>) -> &[u8]

Push a string onto the stack.

The string can contain any binary data, including embedded zeros.

Lua will make or reuse an internal copy of the given string, so the memory pointed to by data can be safely freed or reused immediately after the function returns.

See also Thread::push_c_chars.

§Errors

The underlying Lua state may raise a memory error.

Examples found in repository?
examples/push_trait.rs (line 34)
33	fn push_into(&self, thread: &LuaThread) {
34		thread.push_string(self.as_bytes());
35	}
More examples
Hide additional examples
examples/string_enum.rs (line 60)
55unsafe extern "C-unwind" fn l_main(l: *mut LuaState) -> c_int {
56	let lua = unsafe { LuaThread::from_ptr_mut(l) };
57	let mut test = move |variant: &[u8]| {
58		lua.run_managed(move |mut mg| {
59			mg.push_c_function(l_test);
60			mg.push_string(variant);
61			unsafe { mg.call(1, 0) }
62		})
63	};
64	test(b"udp");
65	test(b"tcp");
66	test(b"unix udp");
67	test(b"unix tcp");
68	test(b"invalid");
69	0
70}
examples/interpreter.rs (line 80)
55unsafe extern "C-unwind" fn l_main(l: *mut LuaState) -> c_int {
56	let lua = unsafe { LuaThread::from_ptr_mut(l) };
57
58	lua.check_version();
59	lua.run_managed(|mut mg| mg.open_libs());
60
61	lua.push_c_function(l_err_handler);
62	let base = lua.top();
63
64	let mut arguments = args().skip(1);
65	let load_status = if let Some(mut file_name) = arguments.next() {
66		lua.load_file(unsafe {
67			file_name.push('\0');
68			CStr::from_bytes_until_nul(file_name.as_bytes()).unwrap_unchecked()
69		})
70	} else {
71		lua.load_stdin()
72	};
73
74	if !report(lua, load_status) {
75		return 0
76	}
77
78	let mut arg_count: c_uint = 0;
79	for arg in arguments {
80		lua.push_string(arg.as_bytes());
81		arg_count += 1;
82	}
83
84	let run_status = lua.run_managed(|mut mg| {
85		mg.restart_gc();
86		let run_status = unsafe { mg.pcall(arg_count, 0, base) };
87		mg.stop_gc();
88		run_status
89	});
90	if !report(lua, run_status) {
91		return 0
92	}
93
94	lua.push_boolean(true);
95	1
96}
examples/hello_lib.rs (line 11)
4unsafe extern "C-unwind" fn l_hello(l: *mut LuaState) -> c_int {
5	// SAFETY: Caller ensures `l` is valid.
6	let lua = unsafe { LuaThread::from_ptr(l) };
7
8	let n = lua.check_number(1);
9
10	// SAFETY: Ditto.
11	lua.push_string("Hello, world!");
12	lua.push_number(n * core::f64::consts::PI as LuaNumber);
13
14	2
15}
examples/os2.rs (lines 29-37)
11unsafe extern "C-unwind" fn l_metadata(l: *mut LuaState) -> c_int {	
12	let lua = unsafe { LuaThread::from_ptr_mut(l) };
13	let path = lua.check_string(1);
14	
15	let meta = match metadata(String::from_utf8_lossy(path).into_owned()) {
16		Ok(meta) => meta,
17		Err(error) => {
18			lua.push_fail();
19			let mut buf = lua.new_buffer();
20			let _ = write!(buf, "{error}");
21			return 2
22		}
23	};
24
25	lua.run_managed(|mut mg| {
26		mg.create_table(0, 1);
27
28		let file_type = meta.file_type();
29		mg.push_string(if file_type.is_file() {
30			"file"
31		} else if file_type.is_dir() {
32			"directory"
33		} else if file_type.is_symlink() {
34			"symlink"
35		} else {
36			"other"
37		}.as_bytes());
38		mg.set_field(-2, c"type");
39
40		mg.push_integer(meta.len() as _);
41		mg.set_field(-2, c"len");
42
43		if let Ok(time) = meta.modified() {
44			if let Ok(time) = time.duration_since(SystemTime::UNIX_EPOCH) {
45				mg.push_number(time.as_secs_f64());
46				mg.set_field(-2, c"modified");
47			}
48		}
49	});
50
51	1
52}
Source

pub fn push_nil(&self)

Push nil onto the stack.

Examples found in repository?
examples/push_trait.rs (line 16)
15	fn push_into(&self, thread: &LuaThread) {
16		thread.push_nil();
17	}
18}
19
20impl Push<1> for LuaInteger {
21	fn push_into(&self, thread: &LuaThread) {
22		thread.push_integer(*self);
23	}
24}
25
26impl Push<1> for LuaNumber {
27	fn push_into(&self, thread: &LuaThread) {
28		thread.push_number(*self);
29	}
30}
31
32impl Push<1> for &str {
33	fn push_into(&self, thread: &LuaThread) {
34		thread.push_string(self.as_bytes());
35	}
36}
37
38impl<T: Push<1>, E: Push<1>> Push<2> for Result<T, E> {
39	fn push_into(&self, thread: &LuaThread) {
40		match self {
41			Self::Ok(t) => {
42				t.push_into(thread);
43				thread.push_nil()
44			}
45			Self::Err(e) => {
46				thread.push_fail();
47				e.push_into(thread)
48			}
49		}
50	}
Source

pub fn push_number(&self, value: Number)

Push a Number onto the stack.

Examples found in repository?
examples/push_trait.rs (line 28)
27	fn push_into(&self, thread: &LuaThread) {
28		thread.push_number(*self);
29	}
More examples
Hide additional examples
examples/hello_lib.rs (line 12)
4unsafe extern "C-unwind" fn l_hello(l: *mut LuaState) -> c_int {
5	// SAFETY: Caller ensures `l` is valid.
6	let lua = unsafe { LuaThread::from_ptr(l) };
7
8	let n = lua.check_number(1);
9
10	// SAFETY: Ditto.
11	lua.push_string("Hello, world!");
12	lua.push_number(n * core::f64::consts::PI as LuaNumber);
13
14	2
15}
examples/os2.rs (line 45)
11unsafe extern "C-unwind" fn l_metadata(l: *mut LuaState) -> c_int {	
12	let lua = unsafe { LuaThread::from_ptr_mut(l) };
13	let path = lua.check_string(1);
14	
15	let meta = match metadata(String::from_utf8_lossy(path).into_owned()) {
16		Ok(meta) => meta,
17		Err(error) => {
18			lua.push_fail();
19			let mut buf = lua.new_buffer();
20			let _ = write!(buf, "{error}");
21			return 2
22		}
23	};
24
25	lua.run_managed(|mut mg| {
26		mg.create_table(0, 1);
27
28		let file_type = meta.file_type();
29		mg.push_string(if file_type.is_file() {
30			"file"
31		} else if file_type.is_dir() {
32			"directory"
33		} else if file_type.is_symlink() {
34			"symlink"
35		} else {
36			"other"
37		}.as_bytes());
38		mg.set_field(-2, c"type");
39
40		mg.push_integer(meta.len() as _);
41		mg.set_field(-2, c"len");
42
43		if let Ok(time) = meta.modified() {
44			if let Ok(time) = time.duration_since(SystemTime::UNIX_EPOCH) {
45				mg.push_number(time.as_secs_f64());
46				mg.set_field(-2, c"modified");
47			}
48		}
49	});
50
51	1
52}
Source

pub fn push_c_str<'l>(&'l self, data: &CStr) -> &'l CStr

Push a zero-terminated string onto the stack.

Lua will make or reuse an internal copy of the given string, so the memory pointed to by data can be freed or reused immediately after the function returns.

See also Thread::push_c_chars and Thread::push_string.

§Errors

The underlying Lua state may raise a memory error.

Source

pub fn push_thread(&self) -> bool

Push the Lua thread represented by this Thread onto its own stack, and return true if this thread is the main thread (see also Lua).

Source

pub fn push_value(&self, index: c_int)

Push a copy of the element at the given index onto the stack.

Source

pub fn raw_equal(&self, idx_a: c_int, idx_b: c_int) -> bool

Return true if the two values in indices idx_a and idx_b are primitively equal (that is, equal without calling the __eq metamethod).

This also returns false if any of the indices are not valid.

Source

pub unsafe fn raw_get(&self, tbl_index: c_int) -> Type

Without calling metamethods, push t[k], where t is the value at the given index and k is the value on the top of the stack.

§Safety

The value at tbl_index must be a table.

Source

pub unsafe fn raw_get_i(&self, tbl_index: c_int, i: Integer) -> Type

Without calling metamethods, push t[i], where t is the value at the given index.

§Safety

The value at tbl_index must be a table.

Source

pub unsafe fn raw_get_p(&self, tbl_index: c_int, ptr: *const c_void) -> Type

Without calling metamethods, push t[ptr], where t is the value at the given index and ptr is the given pointer represented as a light userdata.

§Safety

The value at tbl_index must be a table.

Source

pub fn raw_length(&self, index: c_int) -> Unsigned

Return the raw “length” of the value at the given index.

For strings, this is the string length; for tables, this is the result of the length operator (#) with no metamethods; for userdata, this is the size of the block of memory allocated for the userdata. For other values, this call returns 0.

Source

pub unsafe fn raw_set(&self, tbl_index: c_int)

Without metamethods, do t[k] = v, where t is the value at the given index, v is the value on the top of the stack, and k is the value just below the top.

§Errors

The underlying Lua state may raise a memory error.

§Safety

The value at tbl_index must be a table.

Source

pub unsafe fn raw_set_i(&self, tbl_index: c_int, i: Integer)

Without metamethods, do t[i] = v, where t is the value at the given index and v is the value on the top of the stack.

§Errors

The underlying Lua state may raise a memory error.

§Safety

The value at tbl_index must be a table.

Source

pub unsafe fn raw_set_p(&self, tbl_index: c_int, ptr: *const c_void)

Without metamethods, do t[ptr] = v, where t is the value at the given index, v is the value on the top of the stack, and ptr is the given pointer represented as a light userdata.

§Errors

The underlying Lua state may raise a memory error.

§Safety

The value at tbl_index must be a table.

Source

pub fn register(&self, name: &CStr, func: CFunction)

Set the C function func as the new value of global name.

§Errors

The underlying Lua state may raise an arbitrary error.

Source

pub fn remove(&self, index: c_int)

Remove the element at the given valid index, shifting down the elements above this index to fill the gap.

This function cannot be called with a pseudo-index, because a pseudo-index is not an actual stack position.

Source

pub fn replace(&self, index: c_int)

Move the top element into the given valid index without shifting any element (therefore replacing the value at that given index), and then pop that top element.

Source

pub fn rotate(&self, index: c_int, n_values: c_int)

Rotate the stack elements between the valid index index and the top of the stack.

The elements are rotated n positions in the direction of the top for a ositive n, or -n positions in the direction of the bottom for a negative n. The absolute value of n must not be greater than the size of the slice being rotated.

This function cannot be called with a pseudo-index, because a pseudo-index is not an actual stack position.

Source

pub fn set_global(&self, key: &CStr)

Pop a value from the stack and set it as the new value of global name.

§Errors

The underlying Lua state may raise an arbitrary error.

Source

pub fn set_i_uservalue(&self, ud_index: c_int, n: c_int) -> bool

Pop a value from the stack and set it as the new n-th user value associated to the full userdata at the given index.

Returns false if the userdata does not have that value.

Source

pub fn set_metatable(&self, obj_index: c_int)

Pop a table or nil from the stack and sets that value as the new metatable for the value at the given index. (nil means no metatable.)

Source

pub unsafe fn set_warn_fn(&self, warn: WarnFunction, warn_data: *mut c_void)

Set the warning function to be used by Lua to emit warnings (see WarnFunction).

See also Thread::remove_warn_fn.

§Safety

warn_data is the custom data to be passed to the warning function. It must be valid for warn.

Source

pub fn remove_warn_fn(&self)

Remove the warning function to be used by Lua to emit warnings.

See also Thread::set_warn_fn.

Source

pub fn status(&self) -> Status

Return the status of the Lua thread represented by this Thread.

The status can be Status::Ok for a normal thread, an error variant if the thread finished the execution of a Managed::resume with an error, or Status::Yielded if the thread is suspended.

Functions can only be called in threads with status Status::Ok. Threads with status Status::Ok or Status::Yielded can be resumed (to start a new coroutine or resume an existing one).

Source

pub fn to_boolean(&self, idx: c_int) -> bool

Convert the Lua value at the given index to a bool.

Like all tests in Lua, this returns true for any Lua value different from false and nil; otherwise it returns false.

If you want to accept only actual boolean values, use Thread::is_boolean to test the value’s type first.

Examples found in repository?
examples/interpreter.rs (line 103)
98fn main() -> ExitCode {
99	let mut lua = Lua::new();
100
101	lua.push_c_function(l_main);
102	let status = lua.run_managed(|mut mg| unsafe { mg.pcall(0, 1, 0) });
103	let is_ok = lua.to_boolean(-1);
104	report(&mut lua, status);
105
106	if status.is_ok() && is_ok {
107		ExitCode::SUCCESS
108	} else {
109		ExitCode::FAILURE
110	}
111}
More examples
Hide additional examples
examples/hello.rs (line 47)
41fn main() {
42	let mut lua = Lua::new();
43
44	let did_run_ok = lua.run_managed(move |mut mg| {
45		mg.push_c_function(l_main);
46		if unsafe { mg.pcall(0, 1, 0).is_ok() } {
47			mg.to_boolean(-1)
48		} else {
49			false
50		}
51	});
52	if !did_run_ok {
53		panic!("couldn't run \"Hello, world!\" example for some reason");
54	}
55}
Source

pub fn to_c_function(&self, index: c_int) -> Option<CFunction>

Convert a value at the given index to a C function. If it is not one, return None.

Source

pub unsafe fn to_close(&self, index: c_int)

Mark the given index in the stack as a to-be-closed slot.

Like a to-be-closed variable in Lua, the value at that slot in the stack will be closed when it goes out of scope. Here, in the context of a C function, to go out of scope means that the running function returns to Lua, or there is an error, or the slot is removed from the stack through Managed::set_top or Managed::pop, or there is a call to Managed::close_slot.

A slot marked as to-be-closed should not be removed from the stack by any other function in the API except Managed::set_top or Managed::pop, unless previously deactivated by Managed::close_slot.

§Errors

The underlying Lua state may raise a memory error.

§Safety

This function should not be called for an index that is equal to or below an active to-be-closed slot.

Note that, both in case of errors and of a regular return, by the time the __close metamethod runs, the C stack was already unwound, so that any automatic C variable declared in the calling function (e.g., a buffer) will be out of scope.

Source

pub fn to_integer(&self, idx: c_int) -> Integer

This behaves exactly the same as Thread::to_integer_opt, however the return value is 0 if an integer isn’t present.

Source

pub fn to_integer_opt(&self, idx: c_int) -> Option<Integer>

Convert the Lua value at the given index to the signed integral type Integer.

The Lua value must be an integer, or a number or string convertible to an integer. Otherwise, this function returns None.

Source

pub fn to_c_chars(&self, index: c_int) -> Option<&[c_char]>

Convert the Lua value at the given index to a slice of c_chars, representing a Lua string.

This function works like Thread::to_string.

§Errors

The underlying Lua state may raise a memory error.

Source

pub fn to_c_str(&self, index: c_int) -> Option<&CStr>

Convert the Lua value at the given index to a CStr, representing a Lua string.

This function works like Thread::to_string.

§Errors

The underlying Lua state may raise a memory error.

Examples found in repository?
examples/interpreter.rs (line 24)
22fn report(lua: &mut LuaThread, status: LuaStatus) -> bool {
23	if !status.is_ok() {
24		if let Some(message) = lua.to_c_str(-1) {
25			c_eprintln(message);
26		}
27		lua.run_managed(|mut mg| unsafe { mg.pop(1) });
28		false
29	} else {
30		true
31	}
32}
33
34unsafe extern "C-unwind" fn l_err_handler(l: *mut LuaState) -> c_int {
35	let lua = unsafe { LuaThread::from_ptr_mut(l) };
36
37	if let Some(msg) = lua.to_c_str(1) {
38		lua.traceback(lua, Some(msg), 1);
39		return 1
40	}
41
42	let ok = lua.run_managed(|mut mg| unsafe {
43		mg.call_metamethod(1, c"__tostring")
44	});
45
46	if ok && lua.type_of(-1) == LuaType::String {
47		return 1
48	}
49
50	unsafe { lua_push_fmt_string!(lua, c"(error object is a %s value)", lua.type_name_of(1)) };
51
52	1
53}
Source

pub fn to_string(&self, index: c_int) -> Option<&[u8]>

Convert the Lua value at the given index to a slice of u8s, representing a Lua string.

The Lua value must be a string or a number; otherwise, the function returns None.

If the value is a number, then this function also changes the actual value in the stack to a string.

The function returns a slice to data inside the Lua state. This string always has a zero ('\0') after its last character (as in C), but can contain other zeros in its body.

§Errors

The underlying Lua state may raise a memory error.

Examples found in repository?
examples/push_trait.rs (line 79)
63fn main() {
64	let mut lua = Lua::new();
65	lua.run_managed(|mut mg| mg.open_libs());
66
67	if !lua.load_string(PRINT_CODE.as_bytes(), PRINT_CODE_LUA_NAME).is_ok() {
68		panic!("couldn't load Lua chunk");
69	}
70
71	lua.push(4 as LuaInteger);
72	lua.push(3.1 as LuaNumber);
73	lua.push("how");
74
75	if !lua.run_managed(|mut mg| {
76		mg.restart_gc();
77		unsafe { mg.pcall(3, 0, 0) }
78	}).is_ok() {
79		let error_bytes = lua.to_string(-1);
80		panic!(
81			"error while running Lua chunk: {}",
82			error_bytes.map(String::from_utf8_lossy)
83				.unwrap_or(std::borrow::Cow::Borrowed("<no message>"))
84		);
85	}
86}
More examples
Hide additional examples
examples/hello.rs (line 16)
6unsafe extern "C-unwind" fn l_main(l: *mut LuaState) -> c_int {
7	let lua = unsafe { LuaThread::from_ptr_mut(l) };
8	lua.run_managed(move |mut mg| mg.open_libs());
9
10	let is_ok = lua.load_string(
11		r#"print("Hello, world!")"#,
12		c"=<embedded>"
13	).is_ok();
14	if !is_ok {
15		let error = {
16			lua.to_string(-1)
17				.and_then(move |bytes| core::str::from_utf8(bytes).ok())
18				.unwrap_or("<message is not UTF-8>")
19		};
20		eprintln!("couldn't load example Lua code:\n\t{error}");
21		lua.push_boolean(false);
22		return 1
23	}
24
25	let is_ok = lua.run_managed(move |mut mg| unsafe { mg.pcall(0, 0, 0).is_ok() });
26	if !is_ok {
27		let error = {
28			lua.to_string(-1)
29				.and_then(move |bytes| core::str::from_utf8(bytes).ok())
30				.unwrap_or("<message is not UTF-8>")
31		};
32		eprintln!("couldn't run example Lua code:\n\t{error}");
33		lua.push_boolean(false);
34		return 1
35	}
36
37	lua.push_boolean(true);
38	1
39}
Source

pub fn to_number(&self, idx: c_int) -> Number

This behaves exactly the same as Thread::to_number_opt, however the return value is 0.0 if a number isn’t present.

Source

pub fn to_number_opt(&self, idx: c_int) -> Option<Number>

Convert the Lua value at the given index to the floating-point number type Number.

The Lua value must be a number or string convertible to a number. Otherwise, this function returns None.

Source

pub fn to_pointer(&self, idx: c_int) -> *const c_void

Convert the value at the given index to a generic C pointer (*const c_void).

The value can be a userdata, a table, a thread, a string, or a function; otherwise, this function returns null.

Different objects will give different pointers. There is no way to convert the pointer back to its original value.

Typically this function is used only for hashing and debug information.

Source

pub fn to_thread(&self, index: c_int) -> *mut State

Convert the value at the given index to a Lua thread, represented by a *mutState.

The value must be a thread; otherwise, the function returns null.

Source

pub fn to_userdata(&self, idx: c_int) -> *mut c_void

If the value at the given index is a light or full userdata, return the address it represents. Otherwise, return null.

Source

pub fn type_of(&self, idx: c_int) -> Type

Return the type of the value in the given valid index, or Type::None for a non-valid but acceptable index.

Examples found in repository?
examples/interpreter.rs (line 46)
34unsafe extern "C-unwind" fn l_err_handler(l: *mut LuaState) -> c_int {
35	let lua = unsafe { LuaThread::from_ptr_mut(l) };
36
37	if let Some(msg) = lua.to_c_str(1) {
38		lua.traceback(lua, Some(msg), 1);
39		return 1
40	}
41
42	let ok = lua.run_managed(|mut mg| unsafe {
43		mg.call_metamethod(1, c"__tostring")
44	});
45
46	if ok && lua.type_of(-1) == LuaType::String {
47		return 1
48	}
49
50	unsafe { lua_push_fmt_string!(lua, c"(error object is a %s value)", lua.type_name_of(1)) };
51
52	1
53}
Source

pub fn type_name(&self, type_tag: Type) -> &CStr

Return the name of the type encoded by type_tag.

Source

pub fn version(&self) -> Number

Return the version number of the Lua core.

Source

pub fn warning(&self, message: &CStr, to_be_continued: bool)

Emit a warning with the given message.

A message in a call with to_be_continued == true should be continued in another call to this function.

Source

pub fn xmove(&self, to: &Self, n_values: c_uint)

Exchange values between different threads of the same state.

This function pops n_values values from the stack of this thread, and pushes them onto the stack of the thread to.

Source

pub unsafe fn yield_with(&self, n_results: c_int) -> !

This behaves exactly like Thread::yield_k_with, however there is no continuation.

§Safety

This function should be called only outside of hooks. It is Undefined Behavior if the code after a call to this function is reachable.

Source

pub unsafe fn yield_in_hook_with(&self, n_results: c_int)

This behaves exactly like Thread::yield_in_hook_k_with, however there is no continuation.

§Safety

This function should be called only outside of hooks. It is Undefined Behavior if the code after a call to this function is unreachable.

Source

pub unsafe fn yield_k_with( &self, n_results: c_int, continuation: KFunction, context: KContext, ) -> !

Yield this thread (like a coroutine).

When this function is called, the running coroutine suspends its execution, and the call to Managed::resume that started this coroutine returns.

The parameter n_results is the number of values from the stack that will be passed as results to Managed::resume.

When the coroutine is resumed again, Lua calls the given continuation function continuation to continue the execution of the C function that yielded. This continuation function receives the same stack from the previous function, with the n_results results removed and replaced by the arguments passed to Managed::resume. Moreover, the continuation function receives the value context that was originally passed.

Usually, this function does not return; when the coroutine eventually resumes, it continues executing the continuation function. However, there is one special case, which is when this function is called from inside a line or a count hook (see Hook). In that case, Thread::yield_in_hook_with should be called (thus, no continuation) and no results, and the hook should return immediately after the call. Lua will yield and, when the coroutine resumes again, it will continue the normal execution of the (Lua) function that triggered the hook.

§Errors

The underlying Lua thread can raise an error if the function is called from a thread with a pending C call with no continuation function (what is called a C-call boundary), or it is called from a thread that is not running inside a resume (typically the main thread).

§Safety

This function should be called only outside of hooks. It is Undefined Behavior if the code after a call to this function is reachable.

Source

pub unsafe fn yield_in_hook_k_with( &self, n_results: c_int, continuation: KFunction, context: KContext, )

This behaves exactly like Thread::yield_k_with, however it should only be called in hooks.

§Errors

The underlying Lua thread can raise an error if the function is called from a thread with a pending C call with no continuation function (what is called a C-call boundary), or it is called from a thread that is not running inside a resume (typically the main thread).

§Safety

This function should be called only inside of hooks.

Source

pub unsafe fn debug<const ID_SIZE: usize>(&self) -> ThreadDebug<'_, ID_SIZE>

Returns a ThreadDebug structure that exposes various functions operating on Debug structures.

§Safety

ID_SIZE must be the appropriate identifier size for the underlying Lua state. See DEFAULT_ID_SIZE for the default.

Source

pub fn hook_count(&self) -> c_int

Return the current hook count.

Source

pub fn hook_mask(&self) -> HookMask

Return the current hook mask.

See also HookMask.

Source

pub fn get_upvalue(&self, func_index: c_int, n: u8) -> Option<&CStr>

Get information about the n-th upvalue of the closure at index func_index.

This function pushes the upvalue’s value onto the stack and returns its name. Returns None (and pushes nothing) when the index n is greater than the number of upvalues.

Source

pub fn set_upvalue(&self, func_index: c_int, n: u8) -> Option<&CStr>

Set the value of a closure’s upvalue and return its name.

Returns None (and pops nothing) when the index n is greater than the number of upvalues.

This function assigns the value on the top of the stack to the upvalue. It also pops the value from the stack.

Source

pub unsafe fn upvalue_id(&self, func_index: c_int, n: u8) -> *mut c_void

Return a unique identifier for the upvalue numbered n from the closure at index func_index.

These unique identifiers allow a program to check whether different closures share upvalues. Lua closures that share an upvalue (that is, that access a same external local variable) will return identical ids for those upvalue indices.

§Safety

The returned pointer may only be used for comparisons.

Source

pub fn upvalue_join( &self, func_into_index: i32, n_into: u8, func_from_index: i32, n_from: u8, )

Make the n_into-th upvalue of the Lua closure at index func_into_index refer to the n_from-th upvalue of the Lua closure at index func_from_index.

Source

pub fn new_buffer(&self) -> Buffer<'_>

Construct a new Buffer that’s initialized with this Thread.

Examples found in repository?
examples/os2.rs (line 19)
11unsafe extern "C-unwind" fn l_metadata(l: *mut LuaState) -> c_int {	
12	let lua = unsafe { LuaThread::from_ptr_mut(l) };
13	let path = lua.check_string(1);
14	
15	let meta = match metadata(String::from_utf8_lossy(path).into_owned()) {
16		Ok(meta) => meta,
17		Err(error) => {
18			lua.push_fail();
19			let mut buf = lua.new_buffer();
20			let _ = write!(buf, "{error}");
21			return 2
22		}
23	};
24
25	lua.run_managed(|mut mg| {
26		mg.create_table(0, 1);
27
28		let file_type = meta.file_type();
29		mg.push_string(if file_type.is_file() {
30			"file"
31		} else if file_type.is_dir() {
32			"directory"
33		} else if file_type.is_symlink() {
34			"symlink"
35		} else {
36			"other"
37		}.as_bytes());
38		mg.set_field(-2, c"type");
39
40		mg.push_integer(meta.len() as _);
41		mg.set_field(-2, c"len");
42
43		if let Ok(time) = meta.modified() {
44			if let Ok(time) = time.duration_since(SystemTime::UNIX_EPOCH) {
45				mg.push_number(time.as_secs_f64());
46				mg.set_field(-2, c"modified");
47			}
48		}
49	});
50
51	1
52}
Source

pub fn arg_error(&self, arg: c_int, extra_message: &CStr) -> !

Raise an error reporting a problem with argument arg of the C function that called it, using a standard message that includes extra_message as a comment:

bad argument #<argument> to '<function name>' (<message>)

This function never returns.

Source

pub fn check_any(&self, arg: c_int)

Check whether the function has an argument of any type (including nil) at position arg.

§Errors

The underlying Lua state may raise an error if the argument arg’s type is incorrect.

Source

pub fn check_integer(&self, arg: c_int) -> Integer

Check whether the function argument arg is an integer (or can be converted to an integer) and return this integer.

§Errors

The underlying Lua state may raise an error if the argument arg’s type is incorrect.

Source

pub fn check_c_chars(&self, arg: c_int) -> &[c_char]

Check whether the function argument arg is a string and returns this string represented as a slice of c_chars.

§Errors

The underlying Lua state may raise an error if the argument arg isn’t a string.

Source

pub fn check_string(&self, arg: c_int) -> &[u8]

Works the same as Thread::check_c_chars, however it returns a slice of u8s instead of c_chars.

§Errors

The underlying Lua state may raise an error if the argument arg isn’t a string.

Examples found in repository?
examples/os2.rs (line 13)
11unsafe extern "C-unwind" fn l_metadata(l: *mut LuaState) -> c_int {	
12	let lua = unsafe { LuaThread::from_ptr_mut(l) };
13	let path = lua.check_string(1);
14	
15	let meta = match metadata(String::from_utf8_lossy(path).into_owned()) {
16		Ok(meta) => meta,
17		Err(error) => {
18			lua.push_fail();
19			let mut buf = lua.new_buffer();
20			let _ = write!(buf, "{error}");
21			return 2
22		}
23	};
24
25	lua.run_managed(|mut mg| {
26		mg.create_table(0, 1);
27
28		let file_type = meta.file_type();
29		mg.push_string(if file_type.is_file() {
30			"file"
31		} else if file_type.is_dir() {
32			"directory"
33		} else if file_type.is_symlink() {
34			"symlink"
35		} else {
36			"other"
37		}.as_bytes());
38		mg.set_field(-2, c"type");
39
40		mg.push_integer(meta.len() as _);
41		mg.set_field(-2, c"len");
42
43		if let Ok(time) = meta.modified() {
44			if let Ok(time) = time.duration_since(SystemTime::UNIX_EPOCH) {
45				mg.push_number(time.as_secs_f64());
46				mg.set_field(-2, c"modified");
47			}
48		}
49	});
50
51	1
52}
Source

pub fn check_number(&self, arg: c_int) -> Number

Check whether the function argument arg is a number and return this number converted to a Number.

§Errors

The underlying Lua state may raise an error if the argument arg’s type is incorrect.

Examples found in repository?
examples/hello_lib.rs (line 8)
4unsafe extern "C-unwind" fn l_hello(l: *mut LuaState) -> c_int {
5	// SAFETY: Caller ensures `l` is valid.
6	let lua = unsafe { LuaThread::from_ptr(l) };
7
8	let n = lua.check_number(1);
9
10	// SAFETY: Ditto.
11	lua.push_string("Hello, world!");
12	lua.push_number(n * core::f64::consts::PI as LuaNumber);
13
14	2
15}
Source

pub fn check_option<const N: usize>( &self, arg: c_int, default: Option<&CStr>, list: &AuxOptions<'_, N>, ) -> usize

Check whether the function argument arg is a string, search for this string in the option list list and return the index in the list where the string was found.

If default is Some, the function uses it as a default value when there is no argument arg or when this argument is nil.

This is a useful function for mapping strings to C enums. (The usual convention in Lua libraries is to use strings instead of numbers to select options.)

§Errors

The underlying Lua state may raise an error if the argument arg is not a string or if the string cannot be found in list.

Examples found in repository?
examples/string_enum.rs (line 43)
42	fn check_enum<E: LuaEnum<N>, const N: usize>(&self, arg: c_int) -> E {
43		let index = self.check_option(arg, None, E::OPTIONS);
44		unsafe { E::from_index_unchecked(index) }
45	}
Source

pub fn check_stack(&self, size: c_int, message: Option<&CStr>)

Grow the stack size to top + size elements, raising an error if the stack cannot grow to that size.

message is an additional text to go into the error message (or None for no additional text).

§Errors

The underlying Lua state may raise an error if the Lua stack cannot grow to the given size.

Source

pub fn check_c_str(&self, arg: c_int) -> &CStr

Check whether the function argument arg is a string and return this string represented by a CStr.

§Errors

The underlying Lua state may raise an error if the argument arg isn’t a string.

Source

pub fn check_type(&self, arg: c_int, type_tag: Type)

Check whether the function argument arg has type type_tag.

See also Type.

§Errors

The underlying Lua state may raise an error if the argument arg’s type is incorrect.

Source

pub unsafe fn check_udata( &self, arg: c_int, table_name: &CStr, ) -> NonNull<c_void>

Check whether the function argument arg is a userdata of the type table_name (see also Thread::new_metatable) and return the userdata’s memory-block address (see Thread::to_userdata).

§Errors

The underlying Lua state may raise an error if the argument arg’s type is incorrect.

§Safety

The returned pointer must only be used while it’s valid.

While the metatable of userdata is protected from modification in the Lua standard library, an unsound implementation of setting the metatable of an object in Lua could change a userdatum’s metatable and make the check for the table_name metatable unsound.

Source

pub fn check_version(&self)

Check whether the code making the call and the Lua library being called are using the same version of Lua and the same numeric types.

§Errors

The underlying Lua state may raise an error if the above requirements aren’t met.

Examples found in repository?
examples/interpreter.rs (line 58)
55unsafe extern "C-unwind" fn l_main(l: *mut LuaState) -> c_int {
56	let lua = unsafe { LuaThread::from_ptr_mut(l) };
57
58	lua.check_version();
59	lua.run_managed(|mut mg| mg.open_libs());
60
61	lua.push_c_function(l_err_handler);
62	let base = lua.top();
63
64	let mut arguments = args().skip(1);
65	let load_status = if let Some(mut file_name) = arguments.next() {
66		lua.load_file(unsafe {
67			file_name.push('\0');
68			CStr::from_bytes_until_nul(file_name.as_bytes()).unwrap_unchecked()
69		})
70	} else {
71		lua.load_stdin()
72	};
73
74	if !report(lua, load_status) {
75		return 0
76	}
77
78	let mut arg_count: c_uint = 0;
79	for arg in arguments {
80		lua.push_string(arg.as_bytes());
81		arg_count += 1;
82	}
83
84	let run_status = lua.run_managed(|mut mg| {
85		mg.restart_gc();
86		let run_status = unsafe { mg.pcall(arg_count, 0, base) };
87		mg.stop_gc();
88		run_status
89	});
90	if !report(lua, run_status) {
91		return 0
92	}
93
94	lua.push_boolean(true);
95	1
96}
Source

pub fn error_c_str(&self, message: &CStr) -> !

Raise an error.

This function adds the file name and the line number where the error occurred at the beginning of message, if this information is available.

This function never returns.

Source

pub fn exec_result(&self, status: c_int) -> c_int

Produce the return values for process-related functions in the standard library (os.execute and io.close).

§Errors

The underlying Lua state may raise a memory error.

Source

pub fn file_result(&self, status: c_int, file_name: &CStr) -> c_int

Produce the return values for file-related functions in the standard library (io.open, os.rename, file:seek, etc.).

§Errors

The underlying Lua state may raise a memory error.

Source

pub fn get_meta_field(&self, obj_index: c_int, event: &CStr) -> Type

Push onto the stack the field event from the metatable of the object at index obj_index and return the type of the pushed value.

If the object does not have a metatable, or if the metatable does not have this field, this function pushes nothing and returns Type::Nil.

§Errors

The underlying Lua state may raise a memory error.

Source

pub fn get_aux_metatable(&self, table_name: &CStr) -> Type

Push onto the stack the metatable associated with the name table_name in the registry (see also Thread::new_metatable), or nil if there is no metatable associated with that name, and return the type of the pushed value.

§Errors

The underlying Lua state may raise a memory error.

Source

pub fn load_c_chars(&self, buffer: &[c_char], name: &CStr) -> Status

Load a buffer as a Lua chunk.

This function works like Thread::load_string.

Source

pub fn load_string(&self, buffer: impl AsRef<[u8]>, name: &CStr) -> Status

Load a buffer as a Lua chunk.

This function uses Thread::load to load the chunk in the buffer pointed to by buffer, and will return the same results as that function.

name is the chunk name, used for debug information and error messages.

Examples found in repository?
examples/push_trait.rs (line 67)
63fn main() {
64	let mut lua = Lua::new();
65	lua.run_managed(|mut mg| mg.open_libs());
66
67	if !lua.load_string(PRINT_CODE.as_bytes(), PRINT_CODE_LUA_NAME).is_ok() {
68		panic!("couldn't load Lua chunk");
69	}
70
71	lua.push(4 as LuaInteger);
72	lua.push(3.1 as LuaNumber);
73	lua.push("how");
74
75	if !lua.run_managed(|mut mg| {
76		mg.restart_gc();
77		unsafe { mg.pcall(3, 0, 0) }
78	}).is_ok() {
79		let error_bytes = lua.to_string(-1);
80		panic!(
81			"error while running Lua chunk: {}",
82			error_bytes.map(String::from_utf8_lossy)
83				.unwrap_or(std::borrow::Cow::Borrowed("<no message>"))
84		);
85	}
86}
More examples
Hide additional examples
examples/hello.rs (lines 10-13)
6unsafe extern "C-unwind" fn l_main(l: *mut LuaState) -> c_int {
7	let lua = unsafe { LuaThread::from_ptr_mut(l) };
8	lua.run_managed(move |mut mg| mg.open_libs());
9
10	let is_ok = lua.load_string(
11		r#"print("Hello, world!")"#,
12		c"=<embedded>"
13	).is_ok();
14	if !is_ok {
15		let error = {
16			lua.to_string(-1)
17				.and_then(move |bytes| core::str::from_utf8(bytes).ok())
18				.unwrap_or("<message is not UTF-8>")
19		};
20		eprintln!("couldn't load example Lua code:\n\t{error}");
21		lua.push_boolean(false);
22		return 1
23	}
24
25	let is_ok = lua.run_managed(move |mut mg| unsafe { mg.pcall(0, 0, 0).is_ok() });
26	if !is_ok {
27		let error = {
28			lua.to_string(-1)
29				.and_then(move |bytes| core::str::from_utf8(bytes).ok())
30				.unwrap_or("<message is not UTF-8>")
31		};
32		eprintln!("couldn't run example Lua code:\n\t{error}");
33		lua.push_boolean(false);
34		return 1
35	}
36
37	lua.push_boolean(true);
38	1
39}
Source

pub fn load_file(&self, file_name: &CStr) -> Status

Load a file as a Lua chunk.

This function uses Thread::load to load the chunk in the file file_name.

The first line in the file is ignored if it starts with a #.

§Errors

The underlying Lua state may raise a memory error.

Examples found in repository?
examples/interpreter.rs (lines 66-69)
55unsafe extern "C-unwind" fn l_main(l: *mut LuaState) -> c_int {
56	let lua = unsafe { LuaThread::from_ptr_mut(l) };
57
58	lua.check_version();
59	lua.run_managed(|mut mg| mg.open_libs());
60
61	lua.push_c_function(l_err_handler);
62	let base = lua.top();
63
64	let mut arguments = args().skip(1);
65	let load_status = if let Some(mut file_name) = arguments.next() {
66		lua.load_file(unsafe {
67			file_name.push('\0');
68			CStr::from_bytes_until_nul(file_name.as_bytes()).unwrap_unchecked()
69		})
70	} else {
71		lua.load_stdin()
72	};
73
74	if !report(lua, load_status) {
75		return 0
76	}
77
78	let mut arg_count: c_uint = 0;
79	for arg in arguments {
80		lua.push_string(arg.as_bytes());
81		arg_count += 1;
82	}
83
84	let run_status = lua.run_managed(|mut mg| {
85		mg.restart_gc();
86		let run_status = unsafe { mg.pcall(arg_count, 0, base) };
87		mg.stop_gc();
88		run_status
89	});
90	if !report(lua, run_status) {
91		return 0
92	}
93
94	lua.push_boolean(true);
95	1
96}
Source

pub fn load_stdin(&self) -> Status

Load a Lua chunk from the standard input.

This function uses Thread::load to load the chunk.

The first line in the file is ignored if it starts with a #.

§Errors

The underlying Lua state may raise a memory error.

Examples found in repository?
examples/interpreter.rs (line 71)
55unsafe extern "C-unwind" fn l_main(l: *mut LuaState) -> c_int {
56	let lua = unsafe { LuaThread::from_ptr_mut(l) };
57
58	lua.check_version();
59	lua.run_managed(|mut mg| mg.open_libs());
60
61	lua.push_c_function(l_err_handler);
62	let base = lua.top();
63
64	let mut arguments = args().skip(1);
65	let load_status = if let Some(mut file_name) = arguments.next() {
66		lua.load_file(unsafe {
67			file_name.push('\0');
68			CStr::from_bytes_until_nul(file_name.as_bytes()).unwrap_unchecked()
69		})
70	} else {
71		lua.load_stdin()
72	};
73
74	if !report(lua, load_status) {
75		return 0
76	}
77
78	let mut arg_count: c_uint = 0;
79	for arg in arguments {
80		lua.push_string(arg.as_bytes());
81		arg_count += 1;
82	}
83
84	let run_status = lua.run_managed(|mut mg| {
85		mg.restart_gc();
86		let run_status = unsafe { mg.pcall(arg_count, 0, base) };
87		mg.stop_gc();
88		run_status
89	});
90	if !report(lua, run_status) {
91		return 0
92	}
93
94	lua.push_boolean(true);
95	1
96}
Source

pub fn load_c_str(&self, code: &CStr) -> Status

Load a string as a Lua chunk.

This function uses Thread::load to load code.

Source

pub fn new_lib<const N: usize>(&self, library: &Library<'_, N>)

Create a new table and register there the functions in the list library.

Unlike this function’s C counterpart, this will not call Thread::check_version.

§Errors

The underlying Lua state may raise a memory error.

Examples found in repository?
examples/os2.rs (line 61)
59unsafe extern "C-unwind" fn luaopen_os2(l: *mut LuaState) -> c_int {
60	let lua = LuaThread::from_ptr(l);
61	lua.new_lib(&LIBRARY);
62	1
63}
More examples
Hide additional examples
examples/hello_lib.rs (line 25)
22unsafe extern "C-unwind" fn luaopen_hello(l: *mut LuaState) -> c_int {
23	// SAFETY: Caller ensures `l` is valid.
24	let lua = unsafe { LuaThread::from_ptr(l) };
25	lua.new_lib(&LIBRARY);
26	1
27}
Source

pub fn new_lib_table<const N: usize>(&self, library: &Library<'_, N>)

Create a new table with a size optimized to store all entries in library, but does not actually store them.

This function is intended to be used in conjunction with Thread::set_funcs.

§Errors

The underlying Lua state may raise a memory error.

Source

pub fn new_metatable(&self, table_name: &CStr) -> bool

If the registry already doesn’t have the key table_name, create a new table to be used as a metatable for userdata and return true. Otherwise, return false.

In both cases, the function pushes onto the stack the final value associated with table_name in the registry.

The function adds to this new table the pair __name = table_name, adds to the registry the pair [table_name] = table, and returns true.

§Errors

The underlying Lua state may raise a memory error.

Source

pub fn opt_integer(&self, arg: c_int, default: Integer) -> Integer

If the function argument arg is an integer (or it is convertible to an integer), return this integer, or return default.

§Errors

The underlying Lua state may raise an error if the argument arg isn’t a number, isn’t a nil and not absent.

Source

pub fn opt_c_chars<'l>(&'l self, arg: c_int, default: &'l CStr) -> &'l [c_char]

If the function argument arg is a string, return this string, or return default.

This function works like Thread::opt_string.

§Errors

The underlying Lua state may raise an error if the argument arg isn’t a string, isn’t a nil and not absent.

Source

pub fn opt_c_str<'l>(&'l self, arg: c_int, default: &'l CStr) -> &'l CStr

If the function argument arg is a string, return this string, or return default.

This function works like Thread::opt_string.

§Errors

The underlying Lua state may raise an error if the argument arg isn’t a string, isn’t a nil and not absent.

Source

pub fn opt_string<'l>(&'l self, arg: c_int, default: &'l [u8]) -> &'l [u8]

If the function argument arg is a string, return this string, or return default.

This function uses Thread::to_string to get its result, so all conversions and caveats of that function apply here.

§Errors

The underlying Lua state may raise an error if the argument arg isn’t a string, isn’t a nil and not absent.

Source

pub fn opt_number(&self, arg: c_int, default: Number) -> Number

If the function argument arg is a number, return this number as a Number, or return default.

§Errors

The underlying Lua state may raise an error if the argument arg isn’t a number, isn’t a nil and not absent.

Source

pub fn push_fail(&self)

Pushes the fail value onto the stack.

Examples found in repository?
examples/push_trait.rs (line 46)
39	fn push_into(&self, thread: &LuaThread) {
40		match self {
41			Self::Ok(t) => {
42				t.push_into(thread);
43				thread.push_nil()
44			}
45			Self::Err(e) => {
46				thread.push_fail();
47				e.push_into(thread)
48			}
49		}
50	}
More examples
Hide additional examples
examples/os2.rs (line 18)
11unsafe extern "C-unwind" fn l_metadata(l: *mut LuaState) -> c_int {	
12	let lua = unsafe { LuaThread::from_ptr_mut(l) };
13	let path = lua.check_string(1);
14	
15	let meta = match metadata(String::from_utf8_lossy(path).into_owned()) {
16		Ok(meta) => meta,
17		Err(error) => {
18			lua.push_fail();
19			let mut buf = lua.new_buffer();
20			let _ = write!(buf, "{error}");
21			return 2
22		}
23	};
24
25	lua.run_managed(|mut mg| {
26		mg.create_table(0, 1);
27
28		let file_type = meta.file_type();
29		mg.push_string(if file_type.is_file() {
30			"file"
31		} else if file_type.is_dir() {
32			"directory"
33		} else if file_type.is_symlink() {
34			"symlink"
35		} else {
36			"other"
37		}.as_bytes());
38		mg.set_field(-2, c"type");
39
40		mg.push_integer(meta.len() as _);
41		mg.set_field(-2, c"len");
42
43		if let Ok(time) = meta.modified() {
44			if let Ok(time) = time.duration_since(SystemTime::UNIX_EPOCH) {
45				mg.push_number(time.as_secs_f64());
46				mg.set_field(-2, c"modified");
47			}
48		}
49	});
50
51	1
52}
Source

pub fn create_ref(&self, store_index: c_int) -> c_int

Create and return a reference, in the table at index store_index, for the object on the top of the stack (popping the object).

A reference is a unique integer key. As long as you do not manually add integer keys into the table store_index, this function ensures the uniqueness of the key it returns.

You can retrieve an object referred by the reference ref_idx by calling thread.raw_get_i(store_index, ref_idx). See also Thread::destroy_ref, which frees a reference.

If the object on the top of the stack is nil, this returns the constant REF_NIL. The constant NO_REF is guaranteed to be different from any reference returned.

§Errors

The underlying Lua state may raise a memory error.

Source

pub fn set_funcs<const N: usize>( &self, library: &Library<'_, N>, n_upvalues: u8, )

Registers all functions in the list library into the table on the top of the stack (below optional upvalues).

When n_upvalues is not zero, all functions are created with n_upvalues upvalues, initialized with copies of the values previously pushed on the stack on top of the library table. These values are popped from the stack after the registration.

See also Library.

A value with a None value represents a placeholder, which is filled with false.

§Errors

The underlying Lua state may raise a memory error.

Source

pub fn set_aux_metatable(&self, table_name: &CStr)

Set the metatable of the object on the top of the stack as the metatable associated with name table_name in the registry.

See also Thread::new_metatable.

Source

pub unsafe fn test_udata( &self, arg: c_int, table_name: &CStr, ) -> Option<NonNull<c_void>>

This function works like Thread::check_udata, except that, when the test fails, it returns None instead of raising an error.

§Safety

The returned pointer must only be used while it’s valid.

While the metatable of userdata is protected from modification in the Lua standard library, an unsound implementation of setting the metatable of an object in Lua could change a userdatum’s metatable and make the check for the table_name metatable unsound.

Source

pub fn traceback(&self, of: &Self, message: Option<&CStr>, level: c_int)

Create and push a traceback of the stack of thread of.

If message is Some, it is appended at the beginning of the traceback.

level tells at which level to start the traceback.

§Errors

The underlying Lua state may raise a memory error.

Examples found in repository?
examples/interpreter.rs (line 38)
34unsafe extern "C-unwind" fn l_err_handler(l: *mut LuaState) -> c_int {
35	let lua = unsafe { LuaThread::from_ptr_mut(l) };
36
37	if let Some(msg) = lua.to_c_str(1) {
38		lua.traceback(lua, Some(msg), 1);
39		return 1
40	}
41
42	let ok = lua.run_managed(|mut mg| unsafe {
43		mg.call_metamethod(1, c"__tostring")
44	});
45
46	if ok && lua.type_of(-1) == LuaType::String {
47		return 1
48	}
49
50	unsafe { lua_push_fmt_string!(lua, c"(error object is a %s value)", lua.type_name_of(1)) };
51
52	1
53}
Source

pub fn traceback_self(&self, message: Option<&CStr>, level: c_int)

Create and push a traceback of the stack of this thread to its own stack.

This function works like Thread::traceback.

§Errors

The underlying Lua state may raise a memory error.

Source

pub fn type_error(&self, arg: c_int, type_name: &CStr) -> !

Raise a type error for the argument arg of the C function that called it, using a standard message; type_name is a “name” for the expected type.

This function never returns.

Source

pub fn type_name_of(&self, index: c_int) -> &CStr

Return the name of the type of the value at the given index.

Examples found in repository?
examples/interpreter.rs (line 50)
34unsafe extern "C-unwind" fn l_err_handler(l: *mut LuaState) -> c_int {
35	let lua = unsafe { LuaThread::from_ptr_mut(l) };
36
37	if let Some(msg) = lua.to_c_str(1) {
38		lua.traceback(lua, Some(msg), 1);
39		return 1
40	}
41
42	let ok = lua.run_managed(|mut mg| unsafe {
43		mg.call_metamethod(1, c"__tostring")
44	});
45
46	if ok && lua.type_of(-1) == LuaType::String {
47		return 1
48	}
49
50	unsafe { lua_push_fmt_string!(lua, c"(error object is a %s value)", lua.type_name_of(1)) };
51
52	1
53}
Source

pub fn destroy_ref(&self, store_index: c_int, ref_idx: c_int)

Release the reference ref_idx from the table at index store_index.

If ref_idx is NO_REF or REF_NIL, this function does nothing.

The entry is removed from the table, so that the referred object can be collected. The reference ref_idx is also freed to be used again.

See also Thread::create_ref.

Source

pub fn where_string(&self, level: c_int)

Push onto the stack a string identifying the current position of the control at level level in the call stack.

Typically, this string has the following format:

chunkname:currentline:

Level 0 is the running function, level 1 is the function that called the running function, etc.

This function is used to build a prefix for error messages.

§Errors

The underlying Lua state may raise a memory error.

Trait Implementations§

Source§

impl AsMut<Thread> for Coroutine<'_>

Source§

fn as_mut(&mut self) -> &mut Thread

Converts this type into a mutable reference of the (usually inferred) input type.
Source§

impl AsRef<Thread> for Coroutine<'_>

Source§

fn as_ref(&self) -> &Thread

Converts this type into a shared reference of the (usually inferred) input type.
Source§

impl<'l> Debug for Coroutine<'l>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Deref for Coroutine<'_>

Source§

type Target = Thread

The resulting type after dereferencing.
Source§

fn deref(&self) -> &Self::Target

Dereferences the value.
Source§

impl DerefMut for Coroutine<'_>

Source§

fn deref_mut(&mut self) -> &mut Self::Target

Mutably dereferences the value.

Auto Trait Implementations§

§

impl<'l> Freeze for Coroutine<'l>

§

impl<'l> RefUnwindSafe for Coroutine<'l>

§

impl<'l> Send for Coroutine<'l>

§

impl<'l> Sync for Coroutine<'l>

§

impl<'l> Unpin for Coroutine<'l>

§

impl<'l> !UnwindSafe for Coroutine<'l>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<P, T> Receiver for P
where P: Deref<Target = T> + ?Sized, T: ?Sized,

Source§

type Target = T

🔬This is a nightly-only experimental API. (arbitrary_self_types)
The target type on which the method may be called.
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.