use crate::{
LuaRawTable,
gc::{GcObjectPtr, TablePtr},
lua_value::{
LUA_VFALSE, LUA_VNIL, LUA_VNUMFLT, LUA_VNUMINT, LUA_VTRUE, LuaInnerValue, LuaValue,
},
};
#[derive(Clone, Copy)]
pub struct StkId(*mut LuaValue);
impl StkId {
#[inline(always)]
pub fn from_mut_ptr(ptr: *mut LuaValue) -> Self {
Self(ptr)
}
pub fn from_const_ptr(ptr: *const LuaValue) -> Self {
Self(ptr as *mut LuaValue)
}
#[inline(always)]
pub fn null() -> Self {
Self(std::ptr::null_mut())
}
#[inline(always)]
pub fn from_stack(sp: *mut LuaValue, idx: usize) -> Self {
Self(unsafe { sp.add(idx) })
}
#[inline(always)]
pub fn offset(self, reg: usize) -> Self {
unsafe { Self(self.0.add(reg)) }
}
#[inline(always)]
pub fn is_integer(self) -> bool {
unsafe { (*self.0).tt == LUA_VNUMINT }
}
#[inline(always)]
pub fn is_string(self) -> bool {
unsafe { (*self.0).is_string() }
}
#[inline(always)]
pub fn is_float(self) -> bool {
unsafe { (*self.0).tt == LUA_VNUMFLT }
}
#[inline(always)]
pub fn is_table(self) -> bool {
unsafe { (*self.0).is_table() }
}
#[inline(always)]
pub fn is_nil(self) -> bool {
unsafe { (*self.0).tt == LUA_VNIL }
}
#[inline(always)]
pub fn is_false_or_nil(self) -> bool {
unsafe {
let tt = (*self.0).tt;
tt == LUA_VFALSE || tt == LUA_VNIL
}
}
#[inline(always)]
pub fn is_short_string(self) -> bool {
unsafe { (*self.0).is_short_string() }
}
#[inline(always)]
pub fn tt(self) -> u8 {
unsafe { (*self.0).tt }
}
#[inline(always)]
pub fn ivalue(self) -> i64 {
unsafe { (*self.0).value.i }
}
#[inline(always)]
pub fn fltvalue(self) -> f64 {
unsafe { (*self.0).value.n }
}
#[inline(always)]
pub fn hvalue(self) -> &'static LuaRawTable {
unsafe { (*self.0).hvalue() }
}
#[inline(always)]
pub fn hvalue_mut(self) -> &'static mut LuaRawTable {
unsafe { (*self.0).hvalue_mut() }
}
#[inline(always)]
pub fn as_gc_ptr(self) -> GcObjectPtr {
unsafe { (*self.0).as_gc_ptr_unchecked() }
}
#[inline(always)]
pub fn as_table_ptr(self) -> TablePtr {
unsafe { (*self.0).table_ptr_raw() }
}
#[inline(always)]
pub fn is_collectable(self) -> bool {
unsafe { (*self.0).is_collectable() }
}
#[inline(always)]
pub fn set(self, src: StkId) {
unsafe {
let src = *src.0;
(*self.0).tt = src.tt;
(*self.0).value = src.value;
}
}
#[inline(always)]
pub fn write(self, v: &LuaValue) {
unsafe {
(*self.0).tt = v.tt;
(*self.0).value = v.value;
}
}
#[inline(always)]
pub fn write_parts(self, tt: u8, value: LuaInnerValue) {
unsafe {
(*self.0).tt = tt;
(*self.0).value = value;
}
}
#[inline(always)]
pub fn set_integer(self, i: i64) {
unsafe {
(*self.0).tt = LUA_VNUMINT;
(*self.0).value.i = i;
}
}
#[inline(always)]
pub fn set_float(self, n: f64) {
unsafe {
(*self.0).tt = LUA_VNUMFLT;
(*self.0).value.n = n;
}
}
#[inline(always)]
pub fn set_bool(self, b: bool) {
unsafe {
(*self.0).tt = if b { LUA_VTRUE } else { LUA_VFALSE };
(*self.0).value = LuaInnerValue::NIL;
}
}
#[inline(always)]
pub fn set_nil(self) {
unsafe {
(*self.0).tt = LUA_VNIL;
(*self.0).value = LuaInnerValue::NIL;
}
}
#[inline(always)]
pub fn change_i(self, i: i64) {
unsafe {
(*self.0).value.i = i;
}
}
#[inline(always)]
pub fn change_f(self, n: f64) {
unsafe {
(*self.0).value.n = n;
}
}
#[inline(always)]
pub fn as_ptr(self) -> *mut LuaValue {
self.0
}
#[inline(always)]
pub fn as_const_ptr(self) -> *const LuaValue {
self.0 as *const LuaValue
}
#[inline(always)]
pub fn is_valid(self) -> bool {
!self.0.is_null()
}
#[inline(always)]
pub fn get(self) -> LuaValue {
unsafe { *self.0 }
}
pub fn get_ref(self) -> &'static LuaValue {
unsafe { &*self.0 }
}
pub fn get_parts(self) -> (u8, LuaInnerValue) {
unsafe { ((*self.0).tt, (*self.0).value) }
}
}