opportunistic move

should be way faster now
This commit is contained in:
2023-09-16 12:57:50 +01:00
parent 0bcf10659b
commit 1078835e8b
36 changed files with 535 additions and 521 deletions

View File

@@ -1,4 +1,5 @@
use std::cell::RefCell;
use std::ops::Deref;
use std::rc::Rc;
use crate::foreign::cps_box::{const_cps, init_cps, CPSBox};
@@ -23,31 +24,37 @@ struct SetStateCmd(State);
#[derive(Debug, Clone)]
struct GetStateCmd(State);
define_fn! { SetState = |x| Ok(init_cps(2, SetStateCmd(x.downcast()?))) }
define_fn! { GetState = |x| Ok(init_cps(2, GetStateCmd(x.downcast()?))) }
define_fn! {
SetState = |x| Ok(init_cps(2, SetStateCmd(x.downcast()?)));
GetState = |x| Ok(init_cps(2, GetStateCmd(x.downcast()?)))
}
fn new_state_handler<E>(cmd: &CPSBox<NewStateCmd>) -> Result<ExprInst, E> {
fn new_state_handler<E>(cmd: CPSBox<NewStateCmd>) -> Result<ExprInst, E> {
let (_, default, handler) = cmd.unpack2();
let state = State(Rc::new(RefCell::new(default.clone())));
Ok(call(handler.clone(), [state.atom_exi()]).wrap())
let state = State(Rc::new(RefCell::new(default)));
Ok(call(handler, [state.atom_exi()]).wrap())
}
fn set_state_handler<E>(cmd: &CPSBox<SetStateCmd>) -> Result<ExprInst, E> {
fn set_state_handler<E>(cmd: CPSBox<SetStateCmd>) -> Result<ExprInst, E> {
let (SetStateCmd(state), value, handler) = cmd.unpack2();
*state.0.as_ref().borrow_mut() = value.clone();
Ok(handler.clone())
*state.0.as_ref().borrow_mut() = value;
Ok(handler)
}
fn get_state_handler<E>(cmd: &CPSBox<GetStateCmd>) -> Result<ExprInst, E> {
fn get_state_handler<E>(cmd: CPSBox<GetStateCmd>) -> Result<ExprInst, E> {
let (GetStateCmd(state), handler) = cmd.unpack1();
Ok(call(handler.clone(), [state.0.as_ref().borrow().clone()]).wrap())
let val = match Rc::try_unwrap(state.0) {
Ok(cell) => cell.into_inner(),
Err(rc) => rc.as_ref().borrow().deref().clone(),
};
Ok(call(handler, [val]).wrap())
}
pub fn state_handlers() -> HandlerTable<'static> {
let mut handlers = HandlerTable::new();
handlers.register(new_state_handler);
handlers.register(get_state_handler);
handlers.register(set_state_handler);
handlers.register(|b| new_state_handler(*b));
handlers.register(|b| get_state_handler(*b));
handlers.register(|b| set_state_handler(*b));
handlers
}