From 5c257b0f7478b95f36a23b472399e80569993495 Mon Sep 17 00:00:00 2001 From: luaneko Date: Mon, 30 Jun 2025 06:24:37 +1000 Subject: [PATCH] Update luajit crate docs --- crates/luajit/src/lib.rs | 83 +++++++++++++++++++++++++++++++--------- 1 file changed, 64 insertions(+), 19 deletions(-) diff --git a/crates/luajit/src/lib.rs b/crates/luajit/src/lib.rs index b63ed49..6a8240c 100644 --- a/crates/luajit/src/lib.rs +++ b/crates/luajit/src/lib.rs @@ -35,11 +35,6 @@ pub fn url() -> &'static str { LUAJIT_URL.to_str().unwrap() } -// reexport constants -pub use luajit_sys::{ - LUA_ENVIRONINDEX, LUA_GLOBALSINDEX, LUA_MULTRET, LUA_NOREF, LUA_REFNIL, LUA_REGISTRYINDEX, -}; - /// Lua result. pub type Result = std::result::Result; @@ -76,10 +71,12 @@ enum ErrorInner { } impl Error { + /// Creates a new error with an arbitrary error payload. pub fn new(error: impl Into>) -> Self { Self(ErrorInner::Other(error.into())) } + /// Creates a new error for a type mismatch. pub fn invalid_type(expected: &'static str, got: &'static str) -> Self { Self(ErrorInner::Type { expected, got }) } @@ -426,7 +423,7 @@ impl Chunk { } } - /// Name of this chunk, like `?` or `"@path/to/file.lua"`. + /// Name of this chunk, like `"?"` or `"@path/to/file.lua"`. pub fn name(&self) -> &BStr { self.name.as_ref() } @@ -451,7 +448,7 @@ impl Chunk { /// Assigns a name to this chunk as a path. /// - /// This sets the name of this chunk to `@path`, where `path` is the given path. + /// This sets the name of this chunk to `"@path"`, where `path` is the given path. pub fn with_path(self, path: impl AsRef<[u8]>) -> Self { let mut name = BString::from(b"@"); name.extend_from_slice(path.as_ref()); @@ -631,6 +628,12 @@ impl Drop for GlobalState { } } +/// Key for a [`Ref`] that represents no-reference. +/// +/// This key can always be used safely in [`from_raw`](Ref::from_raw) to create a [`Ref`] that does +/// not reference any value in the registry. If dereferenced, it will always evaluate to `nil`. +pub use luajit_sys::LUA_NOREF; + /// Lua value handle into the registry. /// /// Equivalent to [`luaL_ref`] and [`luaL_unref`] with [`LUA_REGISTRYINDEX`] as the target table. @@ -648,6 +651,13 @@ impl Ref { unsafe { Self::from_raw(stack, luaL_ref(stack.as_ptr(), LUA_REGISTRYINDEX)) } } + /// Creates a new ref from the given key. + /// + /// # Safety + /// + /// `key` must have been created by [`into_raw`](Self::into_raw) or a previous call to + /// [`luaL_ref`] with [`LUA_REGISTRYINDEX`] as the target table. It must also be unique; no two + /// [`Ref`] instances with the same key should exist at the same time. pub unsafe fn from_raw(stack: &State, key: c_int) -> Self { let state = Rc::clone(&stack.thread_ref.state); Self { state, key } @@ -657,7 +667,7 @@ impl Ref { /// /// This key can be used to index into the registry table ([`LUA_REGISTRYINDEX`]) to retrieve /// the referenced value. The key can be converted back into a ref using - /// [`State::new_ref_unchecked`]. + /// [`from_raw`](Ref::from_raw). pub fn into_raw(self) -> c_int { let Self { ref mut state, key } = *ManuallyDrop::new(self); unsafe { ptr::drop_in_place(state) } @@ -948,7 +958,7 @@ impl Stack { (size != 0).then(|| unsafe { self.slot_unchecked(Index::stack(size)) }) } - /// Handle for the value at index `idx`. + /// Slot for the value at index `idx`. /// /// # Panics /// @@ -957,6 +967,11 @@ impl Stack { idx.to_slot(self) } + /// Slot for the value at index `idx`, without checking if the index is valid. + /// + /// # Safety + /// + /// The caller must ensure that the index is valid, i.e. within the bounds of the stack. pub unsafe fn slot_unchecked<'s>(&'s self, idx: Index) -> Slot<'s> { // SAFETY: the caller must ensure that the index is valid unsafe { Slot::new_unchecked(self, idx) } @@ -982,13 +997,16 @@ impl Stack { self.slot(PseudoIndex::Globals) } - /// Pushes the given value at the top of the stack. + /// Pushes the given value to the top of the stack. /// /// Equivalent to the `lua_push*` family of functions depending on the type of `T`. pub fn push<'s, T: Push>(&'s mut self, value: T) { value.push(self); } + /// Pushes the value at index `idx` to the top of the stack. + /// + /// Equivalent to [`lua_pushvalue`]. pub fn push_idx(&mut self, idx: impl ToSlot) { self.push(self.slot(idx).index()); } @@ -1152,7 +1170,7 @@ impl Stack { /// If `j` is [`None`], then it is set to be the value of the field `"n"` interpreted as an /// integer. If this field does not exist, then it is set to the be length of the table as /// defined by the Lua `#` length operator. All values in indices `i` to `j` inclusive are - /// pushed at the top of the stack in ascending order. If `i > j`, then nothing is pushed. + /// pushed to the top of the stack in ascending order. If `i > j`, then nothing is pushed. /// Otherwise, `j - i + 1` values are pushed, and the number of values pushed is returned. /// /// This method does not invoke any metamethods. The table is not popped from the stack or @@ -1204,9 +1222,9 @@ impl Stack { /// Pushes the result of a Lua `require(...)` call onto the stack. /// /// Any return values from the library `name` are pushed. Lua libraries are allowed to return - /// multiple values. If `nret` is not [`LUA_MULTRET`], then the number of return values pushed - /// will be exactly `nret`, filling with nils if necessary. The number values pushed to the - /// stack is returned. + /// multiple values. If `nret` is not [`None`], then the number of return values pushed will be + /// exactly `nret`, filling with nils if necessary. The number values pushed to the stack is + /// returned. /// /// Equivalent to `require(name)`. pub fn require(&mut self, name: impl AsRef<[u8]>, nret: Option) -> Result { @@ -1216,7 +1234,7 @@ impl Stack { self.call(1, nret) } - /// Pushes the given chunk as a function at the top of the stack and returns the slot for the + /// Pushes the given chunk as a function to the top of the stack and returns the slot for the /// new function. /// /// Equivalent to [`lua_loadx`]. @@ -1378,9 +1396,9 @@ impl Stack { /// There must be `narg + 1` values at the top of the stack, including the function to call at /// the index `top - narg` (i.e. the function is pushed first and then `narg` values as /// arguments). All arguments and the function are popped from the stack and then any return - /// values are pushed. If `nret` is not [`LUA_MULTRET`], then the number of return values pushed - /// will be exactly `nret`, filling with nils if necessary. Finally, the number values pushed to - /// the stack is returned. + /// values are pushed. If `nret` is not [`None`], then the number of return values pushed will + /// be exactly `nret`, filling with nils if necessary. Finally, the number values pushed to the + /// stack is returned. /// /// If the thread yields a Rust [`Future`] value, then it will be polled to completion before /// the thread is resumed with the output of the [`Future`] as the argument. If the thread @@ -1629,28 +1647,44 @@ impl<'s> Iterator for StackIter<'s> { /// Index of a value in a [`Stack`]. #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] pub enum Index { + /// Absolute stack index. Stack(NonZero), + /// Upvalue index. Upvalue(NonZero), + /// Pseudo-index. Pseudo(PseudoIndex), } impl Index { + /// Creates a new absolute stack index. + /// + /// # Panics + /// + /// The index must be non-zero. pub fn stack(idx: u32) -> Self { Self::Stack(NonZero::new(idx).expect("stack index cannot be zero")) } + /// Creates a new upvalue index. + /// + /// # Panics + /// + /// The index must be non-zero. pub fn upvalue(idx: u32) -> Self { Self::Upvalue(NonZero::new(idx).expect("upvalue index cannot be zero")) } + /// Creates a new registry table pseudo-index. pub fn registry() -> Self { Self::Pseudo(PseudoIndex::Registry) } + /// Creates a new environment table pseudo-index. pub fn environment() -> Self { Self::Pseudo(PseudoIndex::Environment) } + /// Creates a new globals table pseudo-index. pub fn globals() -> Self { Self::Pseudo(PseudoIndex::Globals) } @@ -1723,10 +1757,14 @@ impl fmt::Display for Index { } } +/// Pseudo-index in a [`Stack`]. #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] pub enum PseudoIndex { + /// Registry table index. Registry, + /// Environment table index. Environment, + /// Globals table index. Globals, } @@ -1776,6 +1814,7 @@ impl<'s> Slot<'s> { Self { stack, idx } } + /// Index of this slot. pub fn index(&self) -> Index { self.idx } @@ -1953,7 +1992,9 @@ impl<'s> fmt::Debug for Slot<'s> { } } +/// Converts a value to a [`Slot`]. pub trait ToSlot { + /// Converts this value to a [`Slot`] on the given stack. fn to_slot<'s>(&self, stack: &'s Stack) -> Slot<'s>; } @@ -2235,7 +2276,7 @@ impl NewTable { } /// Creates a new [`NewTable`] with the array and hash parts set to preallocate `narr` and - /// `rec`. + /// `nrec` respectively. pub fn sized(narr: u32, nrec: u32) -> Self { Self { narr, nrec } } @@ -2255,11 +2296,15 @@ impl Push for NewTable { } } +/// Bare Rust function that can be called from Lua. pub type BareFunction = fn(&mut Stack) -> c_int; +/// [`Push`]es a new function onto a [`Stack`]. #[derive(Debug, Clone, Copy, Hash)] pub enum Function { + /// Bare Rust function. Bare(BareFunction), + /// Raw C function. Raw(lua_CFunction), }