use crate::stack::{Stack, pop, push};
use crate::value::Value;
use std::sync::Arc;
#[allow(improper_ctypes_definitions)]
#[unsafe(no_mangle)]
pub unsafe extern "C" fn patch_seq_make_closure(fn_ptr: u64, env: *mut [Value]) -> Value {
if fn_ptr == 0 {
panic!("make_closure: null function pointer");
}
if env.is_null() {
panic!("make_closure: null environment pointer");
}
let env_box = unsafe { Box::from_raw(env) };
let env_arc: Arc<[Value]> = Arc::from(env_box);
Value::Closure {
fn_ptr: fn_ptr as usize,
env: env_arc,
}
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn patch_seq_push_closure(
mut stack: Stack,
fn_ptr: u64,
capture_count: i32,
) -> Stack {
if fn_ptr == 0 {
panic!("push_closure: null function pointer");
}
if capture_count < 0 {
panic!(
"push_closure: capture_count cannot be negative: {}",
capture_count
);
}
let count = capture_count as usize;
let mut captures: Vec<Value> = Vec::with_capacity(count);
for _ in 0..count {
let (new_stack, value) = unsafe { pop(stack) };
captures.push(value);
stack = new_stack;
}
captures.reverse();
let closure = Value::Closure {
fn_ptr: fn_ptr as usize,
env: Arc::from(captures.into_boxed_slice()),
};
unsafe { push(stack, closure) }
}