mod env;
use std::sync::Arc;
pub use env::*;
use super::{
bindings::*, entities::function::env::FunctionEnv, function::Function, global::Global,
memory::Memory, table::Table,
};
use crate::{
AsStoreMut, BackendFunction, BackendGlobal, BackendMemory, BackendTable, Extern,
v8::store::Store,
};
use wasmer_types::{MemoryError, RawValue};
pub use super::error::Trap;
pub(crate) type VMExtern = *mut wasm_extern_t;
pub(crate) type VMException = ();
pub(crate) type VMTag = *mut wasm_tag_t;
pub(crate) type VMExternTag = *mut wasm_tag_t;
pub(crate) type VMFunction = *mut wasm_func_t;
pub(crate) type VMFunctionBody = ();
pub(crate) type VMFunctionCallback = *mut ::std::os::raw::c_void;
pub(crate) type VMTrampoline = *mut ::std::os::raw::c_void;
pub(crate) type VMExternFunction = *mut wasm_func_t;
pub(crate) type VMGlobal = *mut wasm_global_t;
pub(crate) type VMExternGlobal = *mut wasm_global_t;
pub(crate) type VMTable = *mut wasm_table_t;
pub(crate) type VMExternTable = *mut wasm_table_t;
pub(crate) type VMInstance = *mut wasm_instance_t;
pub(crate) type VMExternObj = ();
pub(crate) type VMConfig = ();
#[allow(clippy::not_unsafe_ptr_arg_deref, clippy::unnecessary_mut_passed)]
#[allow(nonstandard_style)]
impl crate::VMExternToExtern for VMExtern {
fn to_extern(self, store: &mut impl AsStoreMut) -> Extern {
let kind = unsafe { wasm_extern_kind(&mut *self) };
match kind as wasm_valkind_enum {
wasm_externkind_enum_WASM_EXTERN_FUNC => {
let func = unsafe { wasm_extern_as_func(&mut *self) };
if func.is_null() {
panic!("V8 reported extern as function, but is not");
}
Extern::Function(crate::Function::from_vm_extern(
store,
crate::vm::VMExternFunction::V8(func),
))
}
wasm_externkind_enum_WASM_EXTERN_GLOBAL => {
let global = unsafe { wasm_extern_as_global(&mut *self) };
if global.is_null() {
panic!("V8 reported extern as a global, but is not");
}
Extern::Global(crate::Global::from_vm_extern(
store,
crate::vm::VMExternGlobal::V8(global),
))
}
wasm_externkind_enum_WASM_EXTERN_TABLE => {
let table = unsafe { wasm_extern_as_table(&mut *self) };
if table.is_null() {
panic!("V8 reported extern as a table, but is not");
}
Extern::Table(crate::Table::from_vm_extern(
store,
crate::vm::VMExternTable::V8(table),
))
}
wasm_externkind_enum_WASM_EXTERN_MEMORY => {
let memory = unsafe { wasm_extern_as_memory(&mut *self) };
if memory.is_null() {
panic!("V8 reported extern as a memory, but is not");
}
Extern::Memory(crate::Memory::from_vm_extern(
store,
crate::vm::VMExternMemory::V8(memory),
))
}
wasm_externkind_enum_WASM_EXTERN_TAG => {
let tag = unsafe { wasm_extern_as_tag(&mut *self) };
if tag.is_null() {
panic!("V8 reported extern as a tag, but is not");
}
Extern::Tag(crate::Tag::from_vm_extern(
store,
crate::vm::VMExternTag::V8(tag),
))
}
_ => {
unimplemented!()
}
}
}
}
pub(crate) struct VMExternRef(*mut wasm_ref_t);
impl VMExternRef {
pub fn into_raw(self) -> RawValue {
unimplemented!()
}
pub unsafe fn from_raw(_raw: RawValue) -> Option<Self> {
unimplemented!();
}
}
pub(crate) struct VMFuncRef(*mut wasm_ref_t);
impl VMFuncRef {
pub fn into_raw(self) -> RawValue {
unimplemented!()
}
pub unsafe fn from_raw(_raw: RawValue) -> Option<Self> {
unimplemented!();
}
}
pub struct VMExceptionRef(*mut wasm_ref_t);
impl VMExceptionRef {
pub fn into_raw(self) -> RawValue {
unimplemented!()
}
pub unsafe fn from_raw(_raw: RawValue) -> Option<Self> {
unimplemented!();
}
}
#[derive(Debug, Clone)]
pub struct VMMemory(pub(super) *mut wasm_memory_t);
struct SharedMemoryPointer(*mut wasm_shared_memory_t);
pub struct VMSharedMemory(Arc<SharedMemoryPointer>);
pub(crate) type VMExternMemory = *mut wasm_memory_t;
impl SharedMemoryPointer {
fn new(ptr: *mut wasm_shared_memory_t) -> Self {
Self(ptr)
}
}
impl Drop for SharedMemoryPointer {
fn drop(&mut self) {
unsafe {
wasm_shared_memory_delete(self.0);
}
}
}
unsafe impl Send for VMMemory {}
unsafe impl Sync for VMMemory {}
unsafe impl Send for SharedMemoryPointer {}
unsafe impl Sync for SharedMemoryPointer {}
impl VMMemory {
pub(crate) fn as_shared(&self) -> Result<VMSharedMemory, MemoryError> {
let memory_type = unsafe { wasm_memory_type(self.0) };
let limits = unsafe { wasm_memorytype_limits(memory_type) };
if !unsafe { (*limits).shared } {
unsafe {
wasm_memorytype_delete(memory_type);
}
return Err(MemoryError::MemoryNotShared);
}
unsafe {
wasm_memorytype_delete(memory_type);
}
let shared = unsafe { wasm_memory_share(self.0) };
if shared.is_null() {
return Err(MemoryError::Generic(
"Failed to clone the memory".to_string(),
));
}
Ok(VMSharedMemory(Arc::new(SharedMemoryPointer::new(shared))))
}
}
impl VMSharedMemory {
pub(crate) fn clone(&self) -> Self {
Self(self.0.clone())
}
pub(crate) fn into_vm_memory(self, store: &mut Store) -> VMMemory {
let memory = unsafe { wasm_memory_obtain(store.inner, self.0.0) };
assert!(
!memory.is_null(),
"Failed to obtain V8 shared memory: wasm_memory_obtain returned null"
);
VMMemory(memory)
}
}