use core::ops::BitOr;
use crate::{LuaState, ffi};
#[repr(i32)]
#[derive(Debug, PartialEq, Eq)]
pub enum JITMode {
Off = ffi::LUAJIT_MODE_OFF,
On = ffi::LUAJIT_MODE_ON,
Flush = ffi::LUAJIT_MODE_FLUSH,
}
impl From<bool> for JITMode {
#[inline]
fn from(value: bool) -> Self {
if value { Self::On } else { Self::Off }
}
}
impl BitOr<JITMode> for i32 {
type Output = i32;
#[inline]
fn bitor(self, rhs: JITMode) -> Self::Output {
rhs as i32 | self
}
}
impl LuaState {
#[inline]
pub fn jit_set_mode(&self, index: i32, mode: i32) -> bool {
let masked_mode = mode & ffi::LUAJIT_MODE_MASK;
assert!(masked_mode != ffi::LUAJIT_MODE_WRAPCFUNC, "cannot set `LUAJIT_MODE_WRAPCFUNC` by calling `LuaState::jit_set_mode`");
assert!(
(masked_mode != ffi::LUAJIT_MODE_FUNC && masked_mode != ffi::LUAJIT_MODE_ALLFUNC && masked_mode != ffi::LUAJIT_MODE_ALLSUBFUNC) ||
self.is_index_ok(index),
"cannot set the JIT compilation mode of the function at index {index}, as there are only {} elements", self.get_top()
);
unsafe { ffi::luaJIT_setmode(self.0, index, mode) != 0 }
}
#[inline]
pub fn jit_set_engine(&self, mode: impl Into<JITMode>) -> bool {
self.jit_set_mode(0, ffi::LUAJIT_MODE_ENGINE | mode.into())
}
#[inline]
pub fn jit_set_function(&self, index: i32, mode: impl Into<JITMode>, to_self: bool, to_subs: bool) -> bool {
self.jit_set_mode(index, match (to_self, to_subs) {
(true, false) => ffi::LUAJIT_MODE_FUNC,
(true, true) => ffi::LUAJIT_MODE_ALLFUNC,
(false, true) => ffi::LUAJIT_MODE_ALLSUBFUNC,
(false, false) => return false,
} | mode.into())
}
#[inline]
pub fn jit_flush_trace(&self, trace: u32) {
self.jit_set_mode(trace.cast_signed(), ffi::LUAJIT_MODE_TRACE | JITMode::Flush);
}
}