mod call_info;
mod callbacks;
mod lifecycle;
mod thread;
pub(crate) use crate::memory::allocator::VmAllocator;
pub use crate::memory::allocator::{LuaAllocator, SystemLuaAllocator, VM_ALLOC_ALIGN};
pub use call_info::{CallInfo, CallInfoCursor, RawCallInfo, RawCallInfoSaved};
pub use callbacks::{
AllocateCallback, EmbedderGc, EmbedderMark, ExecutionCallbackStorage, ExecutionClose,
ExecutionCounterData, ExecutionDestroy, ExecutionDisable, ExecutionEnter,
ExecutionInlineFunction, ExecutionInterrupt, ExecutionMemorySize, ExecutionTypeMapping,
GcInterrupt, GcInterruptCallback, GcPhase, InterruptKind, InterruptRequest, LuaCallbacks,
LuaExecutionCallbacks, PatternInterrupt, ProtectedErrorAction, ProtectedErrorCallback,
UserAtomCallback, UserThreadCallback,
};
pub use lifecycle::ThreadLifecycle;
pub(crate) use lifecycle::open_main_state;
pub use thread::{RawLuaState, ThreadState};
use core::cell::UnsafeCell;
use core::ptr::NonNull;
use crate::call::LuaProtectedErrorFrame;
use crate::function::RawUpVal;
use crate::gc::{GcStats, RawGcObject};
use crate::handle::RawHandle;
use crate::handle::sealed::Sealed;
use crate::memory::{LUA_MEMORY_CATEGORIES, LUA_SIZE_CLASSES, RawLuaPage};
use crate::metamethod::TM_N;
use crate::string::{RawTString, StringTable};
use crate::table::RawLuaTable;
use crate::thread::{LUA_MIN_STACK, LUAI_MAX_NATIVE_CALLS, Thread};
use crate::types::LUA_T_COUNT;
use crate::userdata::{LuaUserdataDirectAccessData, UserdataTypeRegistry};
use crate::value::{RawTValue, TValue};
#[repr(C)]
pub struct RawMainState {
pub state: RawLuaState,
pub global: RawGlobalState,
}
#[repr(C)]
pub struct RawGlobalState {
pub string_table: StringTable,
pub(crate) allocator: NonNull<VmAllocator>,
pub current_white: u8,
pub gc_state: u8,
pub gray: *mut RawGcObject,
pub gray_again: *mut RawGcObject,
pub weak: *mut RawGcObject,
pub gc_threshold: usize,
pub total_bytes: usize,
pub gc_goal: i32,
pub gc_step_mul: i32,
pub gc_step_size: i32,
pub free_pages: [*mut RawLuaPage; LUA_SIZE_CLASSES],
pub free_gco_pages: [*mut RawLuaPage; LUA_SIZE_CLASSES],
pub all_pages: *mut RawLuaPage,
pub all_gco_pages: *mut RawLuaPage,
pub sweep_gco_page: *mut RawLuaPage,
pub main_thread: *mut RawLuaState,
pub uv_head: RawUpVal,
pub mt: [*mut RawLuaTable; LUA_T_COUNT],
pub tt_name: [*mut RawTString; LUA_T_COUNT],
pub tm_name: [*mut RawTString; TM_N],
pub pseudo_temp: RawTValue,
pub registry: RawTValue,
pub registry_free: i32,
pub protected_error: *mut LuaProtectedErrorFrame,
pub rng_state: u64,
pub ptr_enc_key: [u64; 4],
pub cb: LuaCallbacks,
pub ecb: LuaExecutionCallbacks,
pub ecb_data: ExecutionCallbackStorage,
pub(crate) userdata_type_registry: UnsafeCell<UserdataTypeRegistry>,
pub userdata_direct: [LuaUserdataDirectAccessData; crate::userdata::USERDATA_INTERNAL_LIMIT],
pub memcat_bytes: [usize; LUA_MEMORY_CATEGORIES],
pub userdata_gc: [Option<crate::userdata::LuaDestructor>; crate::userdata::USERDATA_TAG_LIMIT],
pub userdata_mark:
[Option<crate::userdata::LuaUserdataMark>; crate::userdata::USERDATA_TAG_LIMIT],
pub userdata_mt: [*mut RawLuaTable; crate::userdata::USERDATA_TAG_LIMIT],
pub weak_registry: RawTValue,
pub weak_registry_free: i32,
pub embedder_gc: Option<EmbedderGc>,
pub light_userdata_name: [*mut RawTString; crate::userdata::LIGHT_USERDATA_TAG_LIMIT],
pub userdata_direct_fields: [*mut RawLuaTable; crate::userdata::USERDATA_INTERNAL_LIMIT],
pub gc_stats: GcStats,
pub last_proto_id: u32,
}
#[derive(Clone, Copy, PartialEq, Eq)]
#[repr(transparent)]
pub struct GlobalState {
raw: NonNull<RawGlobalState>,
}
#[allow(
clippy::missing_safety_doc,
reason = "GlobalState's shared raw-handle contract is documented on GlobalState"
)]
impl GlobalState {
pub const unsafe fn from_raw(raw: NonNull<RawGlobalState>) -> Self {
Self { raw }
}
pub unsafe fn main_thread(&self) -> Thread {
unsafe {
Thread::from_raw(NonNull::new_unchecked(
self.as_ptr().as_ref().unwrap_unchecked().main_thread,
))
}
}
pub fn encode_pointer(&self, pointer: usize) -> usize {
let keys = unsafe { self.as_ptr().as_ref().unwrap_unchecked().ptr_enc_key };
((keys[0] as usize)
.wrapping_mul(pointer)
.wrapping_add(keys[2] as usize))
^ ((keys[1] as usize)
.wrapping_mul(pointer)
.wrapping_add(keys[3] as usize))
}
pub fn registry(&self) -> TValue {
unsafe { TValue::from_raw(NonNull::new_unchecked(&raw mut (*self.as_ptr()).registry)) }
}
pub fn pseudo_temp(&self) -> TValue {
unsafe {
TValue::from_raw(NonNull::new_unchecked(
&raw mut (*self.as_ptr()).pseudo_temp,
))
}
}
pub fn registry_free(&self) -> i32 {
unsafe { (*self.as_ptr()).registry_free }
}
pub fn set_registry_free(&self, registry_free: i32) {
unsafe {
(*self.as_ptr()).registry_free = registry_free;
}
}
pub(crate) fn weak_registry(&self) -> TValue {
unsafe {
TValue::from_raw(NonNull::new_unchecked(
&raw mut (*self.as_ptr()).weak_registry,
))
}
}
pub(crate) fn weak_registry_free(&self) -> i32 {
unsafe { (*self.as_ptr()).weak_registry_free }
}
pub(crate) fn set_weak_registry_free(&self, registry_free: i32) {
unsafe {
(*self.as_ptr()).weak_registry_free = registry_free;
}
}
pub(crate) fn embedder_gc(&self) -> Option<EmbedderGc> {
unsafe { (*self.as_ptr()).embedder_gc }
}
pub(crate) fn set_embedder_gc(&self, callback: Option<EmbedderGc>) {
unsafe {
(*self.as_ptr()).embedder_gc = callback;
}
}
}
impl Sealed for GlobalState {}
impl RawHandle for GlobalState {
type Raw = RawGlobalState;
fn as_ptr(&self) -> *mut Self::Raw {
self.raw.as_ptr()
}
}
impl AsRef<GlobalState> for GlobalState {
fn as_ref(&self) -> &GlobalState {
self
}
}
pub(crate) const THREAD_STATUS_OK: u8 = 0;
pub(crate) const THREAD_STATUS_YIELD: u8 = 1;
pub(crate) const THREAD_STATUS_ERR_RUN: u8 = 2;
pub(crate) const THREAD_STATUS_ERR_SYNTAX: u8 = 3;
pub(crate) const THREAD_STATUS_ERR_MEM: u8 = 4;
pub(crate) const THREAD_STATUS_ERR_ERR: u8 = 5;
pub(crate) const THREAD_STATUS_BREAK: u8 = 6;
pub(crate) const THREAD_STATUS_SCHEDULED_REENTRY: u8 = 0x7f;
pub const LUA_MEMERRMSG: &[u8] = b"not enough memory";
pub const LUA_ERRERRMSG: &[u8] = b"error in error handling";
pub(crate) const LUA_EXECUTION_CALLBACK_STORAGE: usize = 512;
pub const EXTRA_STACK: usize = 5;
pub const BASIC_CI_SIZE: usize = 8;
pub const BASIC_STACK_SIZE: usize = 2 * LUA_MIN_STACK;
pub const INITIAL_STACK_SIZE: usize = BASIC_STACK_SIZE + EXTRA_STACK;
pub const MAX_NATIVE_CALLS_HARD: u16 = LUAI_MAX_NATIVE_CALLS + (LUAI_MAX_NATIVE_CALLS >> 3);
pub const LUA_CALLINFO_RETURN: u32 = 1 << 0;
pub const LUA_CALLINFO_HANDLE: u32 = 1 << 1;
pub const LUA_CALLINFO_NATIVE: u32 = 1 << 2;
pub const LUA_CALLINFO_OP_YIELD: u32 = 1 << 3;
pub const LUA_OK: i32 = THREAD_STATUS_OK as i32;
pub const LUA_YIELD: i32 = THREAD_STATUS_YIELD as i32;
pub const LUA_ERRRUN: i32 = THREAD_STATUS_ERR_RUN as i32;
pub const LUA_ERRSYNTAX: i32 = THREAD_STATUS_ERR_SYNTAX as i32;
pub const LUA_ERRMEM: i32 = THREAD_STATUS_ERR_MEM as i32;
pub const LUA_ERRERR: i32 = THREAD_STATUS_ERR_ERR as i32;
pub const LUA_BREAK: i32 = THREAD_STATUS_BREAK as i32;