use crate::module::ModuleRegistry;
use crate::prelude::*;
use crate::runtime::vm::{SendSyncPtr, VMArrayCallHostFuncContext, VMFuncRef};
use alloc::sync::Arc;
use core::ptr::NonNull;
#[derive(Default)]
pub struct FuncRefs {
bump: SendSyncBump,
with_holes: Vec<SendSyncPtr<VMFuncRef>>,
instance_pre_func_refs: Vec<Arc<[VMFuncRef]>>,
}
use send_sync_bump::SendSyncBump;
mod send_sync_bump {
#[derive(Default)]
pub struct SendSyncBump(bumpalo::Bump);
impl SendSyncBump {
pub fn alloc<T>(&mut self, val: T) -> &mut T {
self.0.alloc(val)
}
}
unsafe impl Sync for SendSyncBump {}
}
impl FuncRefs {
pub unsafe fn push(&mut self, func_ref: VMFuncRef) -> NonNull<VMFuncRef> {
debug_assert!(func_ref.wasm_call.is_none());
let _ = unsafe { VMArrayCallHostFuncContext::from_opaque(func_ref.vmctx) };
let func_ref = self.bump.alloc(func_ref);
let unpatched = SendSyncPtr::from(func_ref);
let ret = unpatched.as_non_null();
self.with_holes.push(unpatched);
ret
}
pub fn fill(&mut self, modules: &ModuleRegistry) {
self.with_holes.retain_mut(|f| {
unsafe {
let func_ref = f.as_mut();
debug_assert!(func_ref.wasm_call.is_none());
let _ = VMArrayCallHostFuncContext::from_opaque(func_ref.vmctx);
func_ref.wasm_call = modules.wasm_to_array_trampoline(func_ref.type_index);
func_ref.wasm_call.is_none()
}
});
}
pub fn push_instance_pre_func_refs(&mut self, func_refs: Arc<[VMFuncRef]>) {
self.instance_pre_func_refs.push(func_refs);
}
}