use crate::Result;
use crate::frame::ExecutionResult;
use crate::frame::ExecutionResult::Continue;
use crate::frame::Frame;
use crate::operand_stack::OperandStack;
use ristretto_intrinsics::get_monitor_id;
use ristretto_intrinsics::java::lang::thread::{ThreadState, set_thread_status};
#[inline]
pub(crate) async fn monitorenter(
frame: &Frame,
stack: &mut OperandStack,
) -> Result<ExecutionResult> {
let object = stack.pop_object()?;
let Some(reference) = object else {
return Err(crate::JavaError::NullPointerException(Some(
"monitorenter called on null".into(),
))
.into());
};
let monitor_id = get_monitor_id(&reference.read());
if let Some(id) = monitor_id {
let thread = frame.thread()?;
let vm = thread.vm()?;
let monitor = vm.monitor_registry().monitor(id);
let thread_object = thread.java_object().await;
let _ = set_thread_status(&thread_object, ThreadState::BLOCKED);
monitor.acquire(thread.id()).await?;
let _ = set_thread_status(&thread_object, ThreadState::RUNNABLE);
}
Ok(Continue)
}
#[inline]
pub(crate) async fn monitorexit(
frame: &Frame,
stack: &mut OperandStack,
) -> Result<ExecutionResult> {
let object = stack.pop_object()?;
let Some(reference) = object else {
return Err(crate::JavaError::NullPointerException(Some(
"monitorexit called on null".into(),
))
.into());
};
let monitor_id = get_monitor_id(&reference.read());
if let Some(id) = monitor_id {
let thread = frame.thread()?;
let vm = thread.vm()?;
let monitor = vm.monitor_registry().monitor(id);
monitor.release(thread.id())?;
}
Ok(Continue)
}
#[cfg(test)]
mod tests {
}