mirror of
https://github.com/fluencelabs/wasmer
synced 2025-06-24 22:21:32 +00:00
Implement Send for Instance
This commit is contained in:
@ -536,9 +536,8 @@ fn import_functions(
|
|||||||
let namespace = module.info.namespace_table.get(*namespace_index);
|
let namespace = module.info.namespace_table.get(*namespace_index);
|
||||||
let name = module.info.name_table.get(*name_index);
|
let name = module.info.name_table.get(*name_index);
|
||||||
|
|
||||||
let import = imports
|
let import =
|
||||||
.get_namespace(namespace)
|
imports.maybe_with_namespace(namespace, |namespace| namespace.get_export(name));
|
||||||
.and_then(|namespace| namespace.get_export(name));
|
|
||||||
match import {
|
match import {
|
||||||
Some(Export::Function {
|
Some(Export::Function {
|
||||||
func,
|
func,
|
||||||
@ -624,9 +623,8 @@ fn import_memories(
|
|||||||
let namespace = module.info.namespace_table.get(*namespace_index);
|
let namespace = module.info.namespace_table.get(*namespace_index);
|
||||||
let name = module.info.name_table.get(*name_index);
|
let name = module.info.name_table.get(*name_index);
|
||||||
|
|
||||||
let memory_import = imports
|
let memory_import =
|
||||||
.get_namespace(&namespace)
|
imports.maybe_with_namespace(namespace, |namespace| namespace.get_export(name));
|
||||||
.and_then(|namespace| namespace.get_export(&name));
|
|
||||||
match memory_import {
|
match memory_import {
|
||||||
Some(Export::Memory(memory)) => {
|
Some(Export::Memory(memory)) => {
|
||||||
if expected_memory_desc.fits_in_imported(memory.descriptor()) {
|
if expected_memory_desc.fits_in_imported(memory.descriptor()) {
|
||||||
@ -696,9 +694,8 @@ fn import_tables(
|
|||||||
let namespace = module.info.namespace_table.get(*namespace_index);
|
let namespace = module.info.namespace_table.get(*namespace_index);
|
||||||
let name = module.info.name_table.get(*name_index);
|
let name = module.info.name_table.get(*name_index);
|
||||||
|
|
||||||
let table_import = imports
|
let table_import =
|
||||||
.get_namespace(&namespace)
|
imports.maybe_with_namespace(namespace, |namespace| namespace.get_export(name));
|
||||||
.and_then(|namespace| namespace.get_export(&name));
|
|
||||||
match table_import {
|
match table_import {
|
||||||
Some(Export::Table(mut table)) => {
|
Some(Export::Table(mut table)) => {
|
||||||
if expected_table_desc.fits_in_imported(table.descriptor()) {
|
if expected_table_desc.fits_in_imported(table.descriptor()) {
|
||||||
@ -767,9 +764,8 @@ fn import_globals(
|
|||||||
{
|
{
|
||||||
let namespace = module.info.namespace_table.get(*namespace_index);
|
let namespace = module.info.namespace_table.get(*namespace_index);
|
||||||
let name = module.info.name_table.get(*name_index);
|
let name = module.info.name_table.get(*name_index);
|
||||||
let import = imports
|
let import =
|
||||||
.get_namespace(namespace)
|
imports.maybe_with_namespace(namespace, |namespace| namespace.get_export(name));
|
||||||
.and_then(|namespace| namespace.get_export(name));
|
|
||||||
match import {
|
match import {
|
||||||
Some(Export::Global(mut global)) => {
|
Some(Export::Global(mut global)) => {
|
||||||
if global.descriptor() == *imported_global_desc {
|
if global.descriptor() == *imported_global_desc {
|
||||||
|
@ -11,6 +11,8 @@ pub enum Context {
|
|||||||
Internal,
|
Internal,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsafe impl Send for Context {}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub enum Export {
|
pub enum Export {
|
||||||
Function {
|
Function {
|
||||||
@ -26,6 +28,8 @@ pub enum Export {
|
|||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct FuncPointer(*const vm::Func);
|
pub struct FuncPointer(*const vm::Func);
|
||||||
|
|
||||||
|
unsafe impl Send for FuncPointer {}
|
||||||
|
|
||||||
impl FuncPointer {
|
impl FuncPointer {
|
||||||
/// This needs to be unsafe because there is
|
/// This needs to be unsafe because there is
|
||||||
/// no way to check whether the passed function
|
/// no way to check whether the passed function
|
||||||
|
@ -4,11 +4,11 @@ use crate::{
|
|||||||
types::{GlobalDescriptor, Type, Value},
|
types::{GlobalDescriptor, Type, Value},
|
||||||
vm,
|
vm,
|
||||||
};
|
};
|
||||||
use std::{cell::RefCell, fmt, rc::Rc};
|
use std::{cell::RefCell, fmt, sync::Arc};
|
||||||
|
|
||||||
pub struct Global {
|
pub struct Global {
|
||||||
desc: GlobalDescriptor,
|
desc: GlobalDescriptor,
|
||||||
storage: Rc<RefCell<vm::LocalGlobal>>,
|
storage: Arc<RefCell<vm::LocalGlobal>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Global {
|
impl Global {
|
||||||
@ -56,7 +56,7 @@ impl Global {
|
|||||||
|
|
||||||
Self {
|
Self {
|
||||||
desc,
|
desc,
|
||||||
storage: Rc::new(RefCell::new(local_global)),
|
storage: Arc::new(RefCell::new(local_global)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -120,7 +120,7 @@ impl Clone for Global {
|
|||||||
fn clone(&self) -> Self {
|
fn clone(&self) -> Self {
|
||||||
Self {
|
Self {
|
||||||
desc: self.desc,
|
desc: self.desc,
|
||||||
storage: Rc::clone(&self.storage),
|
storage: Arc::clone(&self.storage),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,9 +2,9 @@ use crate::export::Export;
|
|||||||
use std::collections::VecDeque;
|
use std::collections::VecDeque;
|
||||||
use std::collections::{hash_map::Entry, HashMap};
|
use std::collections::{hash_map::Entry, HashMap};
|
||||||
use std::{
|
use std::{
|
||||||
cell::{Ref, RefCell},
|
borrow::{Borrow, BorrowMut},
|
||||||
ffi::c_void,
|
ffi::c_void,
|
||||||
rc::Rc,
|
sync::{Arc, Mutex},
|
||||||
};
|
};
|
||||||
|
|
||||||
pub trait LikeNamespace {
|
pub trait LikeNamespace {
|
||||||
@ -45,8 +45,8 @@ impl IsExport for Export {
|
|||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
pub struct ImportObject {
|
pub struct ImportObject {
|
||||||
map: Rc<RefCell<HashMap<String, Box<dyn LikeNamespace>>>>,
|
map: Arc<Mutex<HashMap<String, Box<dyn LikeNamespace + Send>>>>,
|
||||||
pub(crate) state_creator: Option<Rc<dyn Fn() -> (*mut c_void, fn(*mut c_void))>>,
|
pub(crate) state_creator: Option<Arc<dyn Fn() -> (*mut c_void, fn(*mut c_void)) + Send>>,
|
||||||
pub allow_missing_functions: bool,
|
pub allow_missing_functions: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -54,7 +54,7 @@ impl ImportObject {
|
|||||||
/// Create a new `ImportObject`.
|
/// Create a new `ImportObject`.
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self {
|
Self {
|
||||||
map: Rc::new(RefCell::new(HashMap::new())),
|
map: Arc::new(Mutex::new(HashMap::new())),
|
||||||
state_creator: None,
|
state_creator: None,
|
||||||
allow_missing_functions: false,
|
allow_missing_functions: false,
|
||||||
}
|
}
|
||||||
@ -62,11 +62,11 @@ impl ImportObject {
|
|||||||
|
|
||||||
pub fn new_with_data<F>(state_creator: F) -> Self
|
pub fn new_with_data<F>(state_creator: F) -> Self
|
||||||
where
|
where
|
||||||
F: Fn() -> (*mut c_void, fn(*mut c_void)) + 'static,
|
F: Fn() -> (*mut c_void, fn(*mut c_void)) + 'static + Send,
|
||||||
{
|
{
|
||||||
Self {
|
Self {
|
||||||
map: Rc::new(RefCell::new(HashMap::new())),
|
map: Arc::new(Mutex::new(HashMap::new())),
|
||||||
state_creator: Some(Rc::new(state_creator)),
|
state_creator: Some(Arc::new(state_creator)),
|
||||||
allow_missing_functions: false,
|
allow_missing_functions: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -92,9 +92,10 @@ impl ImportObject {
|
|||||||
pub fn register<S, N>(&mut self, name: S, namespace: N) -> Option<Box<dyn LikeNamespace>>
|
pub fn register<S, N>(&mut self, name: S, namespace: N) -> Option<Box<dyn LikeNamespace>>
|
||||||
where
|
where
|
||||||
S: Into<String>,
|
S: Into<String>,
|
||||||
N: LikeNamespace + 'static,
|
N: LikeNamespace + Send + 'static,
|
||||||
{
|
{
|
||||||
let mut map = self.map.borrow_mut();
|
let mut guard = self.map.lock().unwrap();
|
||||||
|
let map = guard.borrow_mut();
|
||||||
|
|
||||||
match map.entry(name.into()) {
|
match map.entry(name.into()) {
|
||||||
Entry::Vacant(empty) => {
|
Entry::Vacant(empty) => {
|
||||||
@ -105,19 +106,50 @@ impl ImportObject {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_namespace(&self, namespace: &str) -> Option<Ref<dyn LikeNamespace + 'static>> {
|
/*pub fn get_namespace(
|
||||||
let map_ref = self.map.borrow();
|
&self,
|
||||||
|
namespace: &str,
|
||||||
|
) -> Option<
|
||||||
|
MutexGuardRef<HashMap<String, Box<dyn LikeNamespace + Send>>, &(dyn LikeNamespace + Send)>,
|
||||||
|
> {
|
||||||
|
MutexGuardRef::new(self.map.lock().unwrap())
|
||||||
|
.try_map(|mg| mg.get(namespace).map(|ns| &ns.as_ref()).ok_or(()))
|
||||||
|
.ok()
|
||||||
|
}*/
|
||||||
|
|
||||||
|
/// Apply a function on the namespace if it exists
|
||||||
|
/// If your function can fail, consider using `maybe_with_namespace`
|
||||||
|
pub fn with_namespace<Func, InnerRet>(&self, namespace: &str, f: Func) -> Option<InnerRet>
|
||||||
|
where
|
||||||
|
Func: FnOnce(&(dyn LikeNamespace + Send)) -> InnerRet,
|
||||||
|
InnerRet: Sized,
|
||||||
|
{
|
||||||
|
let guard = self.map.lock().unwrap();
|
||||||
|
let map_ref = guard.borrow();
|
||||||
if map_ref.contains_key(namespace) {
|
if map_ref.contains_key(namespace) {
|
||||||
Some(Ref::map(map_ref, |map| &*map[namespace]))
|
Some(f(map_ref[namespace].as_ref()))
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The same as `with_namespace` but takes a function that may fail
|
||||||
|
pub fn maybe_with_namespace<Func, InnerRet>(&self, namespace: &str, f: Func) -> Option<InnerRet>
|
||||||
|
where
|
||||||
|
Func: FnOnce(&(dyn LikeNamespace + Send)) -> Option<InnerRet>,
|
||||||
|
InnerRet: Sized,
|
||||||
|
{
|
||||||
|
let guard = self.map.lock().unwrap();
|
||||||
|
let map_ref = guard.borrow();
|
||||||
|
map_ref
|
||||||
|
.get(namespace)
|
||||||
|
.map(|ns| ns.as_ref())
|
||||||
|
.and_then(|ns| f(ns))
|
||||||
|
}
|
||||||
|
|
||||||
pub fn clone_ref(&self) -> Self {
|
pub fn clone_ref(&self) -> Self {
|
||||||
Self {
|
Self {
|
||||||
map: Rc::clone(&self.map),
|
map: Arc::clone(&self.map),
|
||||||
state_creator: self.state_creator.clone(),
|
state_creator: self.state_creator.clone(),
|
||||||
allow_missing_functions: false,
|
allow_missing_functions: false,
|
||||||
}
|
}
|
||||||
@ -125,7 +157,9 @@ impl ImportObject {
|
|||||||
|
|
||||||
fn get_objects(&self) -> VecDeque<(String, String, Export)> {
|
fn get_objects(&self) -> VecDeque<(String, String, Export)> {
|
||||||
let mut out = VecDeque::new();
|
let mut out = VecDeque::new();
|
||||||
for (name, ns) in self.map.borrow().iter() {
|
let guard = self.map.lock().unwrap();
|
||||||
|
let map = guard.borrow();
|
||||||
|
for (name, ns) in map.iter() {
|
||||||
for (id, exp) in ns.get_exports() {
|
for (id, exp) in ns.get_exports() {
|
||||||
out.push_back((name.clone(), id, exp));
|
out.push_back((name.clone(), id, exp));
|
||||||
}
|
}
|
||||||
@ -158,7 +192,8 @@ impl IntoIterator for ImportObject {
|
|||||||
|
|
||||||
impl Extend<(String, String, Export)> for ImportObject {
|
impl Extend<(String, String, Export)> for ImportObject {
|
||||||
fn extend<T: IntoIterator<Item = (String, String, Export)>>(&mut self, iter: T) {
|
fn extend<T: IntoIterator<Item = (String, String, Export)>>(&mut self, iter: T) {
|
||||||
let mut map = self.map.borrow_mut();
|
let mut guard = self.map.lock().unwrap();
|
||||||
|
let map = guard.borrow_mut();
|
||||||
for (ns, id, exp) in iter.into_iter() {
|
for (ns, id, exp) in iter.into_iter() {
|
||||||
if let Some(like_ns) = map.get_mut(&ns) {
|
if let Some(like_ns) = map.get_mut(&ns) {
|
||||||
like_ns.maybe_insert(&id, exp);
|
like_ns.maybe_insert(&id, exp);
|
||||||
@ -175,6 +210,8 @@ pub struct Namespace {
|
|||||||
map: HashMap<String, Box<dyn IsExport>>,
|
map: HashMap<String, Box<dyn IsExport>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsafe impl Send for Namespace {}
|
||||||
|
|
||||||
impl Namespace {
|
impl Namespace {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self {
|
Self {
|
||||||
|
@ -165,6 +165,8 @@ pub struct Func<'a, Args = (), Rets = (), Inner: Kind = Wasm> {
|
|||||||
_phantom: PhantomData<(&'a (), Args, Rets)>,
|
_phantom: PhantomData<(&'a (), Args, Rets)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsafe impl<'a, Args, Rets> Send for Func<'a, Args, Rets> {}
|
||||||
|
|
||||||
impl<'a, Args, Rets> Func<'a, Args, Rets, Wasm>
|
impl<'a, Args, Rets> Func<'a, Args, Rets, Wasm>
|
||||||
where
|
where
|
||||||
Args: WasmTypeList,
|
Args: WasmTypeList,
|
||||||
|
Reference in New Issue
Block a user