mirror of
https://github.com/fluencelabs/wasmer
synced 2025-06-29 08:31:32 +00:00
Implement table getting and setting
This commit is contained in:
@ -7,9 +7,11 @@ use crate::{
|
|||||||
vm,
|
vm,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use std::convert::TryFrom;
|
||||||
use std::{ptr, sync::Arc};
|
use std::{ptr, sync::Arc};
|
||||||
|
|
||||||
enum AnyfuncInner<'a> {
|
enum AnyfuncInner<'a> {
|
||||||
|
// TODO: update this entry and impl Into/TryFrom
|
||||||
Host {
|
Host {
|
||||||
ptr: *const vm::Func,
|
ptr: *const vm::Func,
|
||||||
signature: Arc<FuncSig>,
|
signature: Arc<FuncSig>,
|
||||||
@ -45,6 +47,17 @@ impl<'a> From<DynFunc<'a>> for Anyfunc<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'a> TryFrom<Anyfunc<'a>> for DynFunc<'a> {
|
||||||
|
type Error = ();
|
||||||
|
|
||||||
|
fn try_from(anyfunc: Anyfunc<'a>) -> Result<Self, Self::Error> {
|
||||||
|
match anyfunc.inner {
|
||||||
|
AnyfuncInner::Managed(df) => Ok(df),
|
||||||
|
_ => Err(()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub struct AnyfuncTable {
|
pub struct AnyfuncTable {
|
||||||
pub(crate) backing: Vec<vm::Anyfunc>,
|
pub(crate) backing: Vec<vm::Anyfunc>,
|
||||||
max: Option<u32>,
|
max: Option<u32>,
|
||||||
|
@ -8,6 +8,7 @@ use crate::{
|
|||||||
vm,
|
vm,
|
||||||
};
|
};
|
||||||
use std::{
|
use std::{
|
||||||
|
convert::TryFrom,
|
||||||
fmt, ptr,
|
fmt, ptr,
|
||||||
sync::{Arc, Mutex},
|
sync::{Arc, Mutex},
|
||||||
};
|
};
|
||||||
@ -18,12 +19,120 @@ pub use self::anyfunc::Anyfunc;
|
|||||||
pub(crate) use self::anyfunc::AnyfuncTable;
|
pub(crate) use self::anyfunc::AnyfuncTable;
|
||||||
use crate::error::GrowError;
|
use crate::error::GrowError;
|
||||||
|
|
||||||
|
/// Error type indicating why a table access failed.
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
|
pub enum TableAccessError {
|
||||||
|
/// The index wasn't valid, so no element could be accessed.
|
||||||
|
IndexError,
|
||||||
|
|
||||||
|
// we'll need this error when we support tables holding more types
|
||||||
|
#[allow(dead_code)]
|
||||||
|
/// The type of the table was incorrect, so no element could be accessed.
|
||||||
|
TypeError,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Trait indicates types that can be stored in tables
|
||||||
|
pub trait StorableInTable: Sized {
|
||||||
|
/// Attempt to lookup self in the given table.
|
||||||
|
fn unwrap_self(storage: &TableStorage, index: u32) -> Result<Self, TableAccessError>;
|
||||||
|
|
||||||
|
/// Wrap value to be stored in a table.
|
||||||
|
fn wrap_self(self, storage: &mut TableStorage, index: u32) -> Result<(), TableAccessError>;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
// this specific impelementation should be unnecessary now
|
||||||
|
// delete it after tests are written
|
||||||
|
|
||||||
|
impl<'a> StorableInTable for Anyfunc<'a> {
|
||||||
|
fn unwrap_self(storage: &TableStorage, index: u32) -> Result<Self, TableAccessError> {
|
||||||
|
match storage {
|
||||||
|
TableStorage::Anyfunc(ref anyfunc_table) => {
|
||||||
|
anyfunc_table.get(index).ok_or(TableAccessError::IndexError)
|
||||||
|
}
|
||||||
|
// TODO: return type error here when we support more than 1 type
|
||||||
|
// _ => Err(TableAccessError::TypeError),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn wrap_self(self, storage: &mut TableStorage, index: u32) -> Result<(), TableAccessError> {
|
||||||
|
match storage {
|
||||||
|
TableStorage::Anyfunc(ref mut anyfunc_table) => anyfunc_table
|
||||||
|
.set(index, self)
|
||||||
|
.map_err(|_| TableAccessError::IndexError),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
impl<'a, F: Into<Anyfunc<'a>> + TryFrom<Anyfunc<'a>>> StorableInTable for F {
|
||||||
|
fn unwrap_self(storage: &TableStorage, index: u32) -> Result<Self, TableAccessError> {
|
||||||
|
match storage {
|
||||||
|
TableStorage::Anyfunc(ref anyfunc_table) => {
|
||||||
|
let anyfunc = anyfunc_table
|
||||||
|
.get(index)
|
||||||
|
.ok_or(TableAccessError::IndexError)?;
|
||||||
|
// Should this be a different error value because it's not a table type error?
|
||||||
|
F::try_from(anyfunc).map_err(|_| TableAccessError::TypeError)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn wrap_self(self, storage: &mut TableStorage, index: u32) -> Result<(), TableAccessError> {
|
||||||
|
let anyfunc: Anyfunc = self.into();
|
||||||
|
|
||||||
|
match storage {
|
||||||
|
TableStorage::Anyfunc(ref mut anyfunc_table) => anyfunc_table
|
||||||
|
.set(index, anyfunc)
|
||||||
|
.map_err(|_| TableAccessError::IndexError),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
// this should be unnecessary if the above generic implementation worked
|
||||||
|
// TODO: remove this commented out code after writing a test
|
||||||
|
// TODO: update `AnyfuncInner` so that `StorableInTable` can be implemented on `Func`, too.
|
||||||
|
|
||||||
|
impl<'a, Args: WasmTypeList, Rets: WasmTypeList> StorableInTable for Func<'a, Args, Rets> {
|
||||||
|
fn unwrap_self(storage: &TableStorage, index: u32) -> Result<Self, TableAccessError> {
|
||||||
|
// TODO:
|
||||||
|
}
|
||||||
|
|
||||||
|
fn wrap_self(self, storage: &mut TableStorage, index: u32) -> Result<(), TableAccessError> {
|
||||||
|
let sig = FuncSig::new(self.params(), self.returns());
|
||||||
|
let anyfunc = Anyfunc::new(self.func.as_ptr(), sig);
|
||||||
|
|
||||||
|
anyfunc.wrap_self(storage, index)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
/// Kind of table element.
|
/// Kind of table element.
|
||||||
|
// note to implementors: all types in `Element` should implement `StorableInTable`.
|
||||||
pub enum Element<'a> {
|
pub enum Element<'a> {
|
||||||
/// Anyfunc.
|
/// Anyfunc.
|
||||||
Anyfunc(Anyfunc<'a>),
|
Anyfunc(Anyfunc<'a>),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// delegation implementation for `Element`
|
||||||
|
impl<'a> StorableInTable for Element<'a> {
|
||||||
|
fn unwrap_self(storage: &TableStorage, index: u32) -> Result<Self, TableAccessError> {
|
||||||
|
match storage {
|
||||||
|
TableStorage::Anyfunc(ref anyfunc_table) => anyfunc_table
|
||||||
|
.get(index)
|
||||||
|
.map(Element::Anyfunc)
|
||||||
|
.ok_or(TableAccessError::IndexError),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn wrap_self(self, storage: &mut TableStorage, index: u32) -> Result<(), TableAccessError> {
|
||||||
|
match self {
|
||||||
|
Element::Anyfunc(af) => af.wrap_self(storage, index),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Kind of table storage.
|
/// Kind of table storage.
|
||||||
// #[derive(Debug)]
|
// #[derive(Debug)]
|
||||||
pub enum TableStorage {
|
pub enum TableStorage {
|
||||||
@ -89,27 +198,19 @@ impl Table {
|
|||||||
self.desc
|
self.desc
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the `Element` at the given index in the table
|
/// Get the raw table value at index. A return value of `None` means either that
|
||||||
pub fn get(&self, index: u32) -> Option<Element> {
|
/// the index or the type wasn't valid.
|
||||||
let storage = self.storage.lock().unwrap();
|
pub fn get<T: StorableInTable>(&self, index: u32) -> Result<T, TableAccessError> {
|
||||||
match &*storage {
|
let guard = self.storage.lock().unwrap();
|
||||||
(TableStorage::Anyfunc(ref anyfunc_table), _) => {
|
let (storage, _) = &*guard;
|
||||||
anyfunc_table.get(index).map(Element::Anyfunc)
|
T::unwrap_self(storage, index)
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set the element at index.
|
/// Set the element at index.
|
||||||
pub fn set(&self, index: u32, element: Element) -> Result<(), ()> {
|
pub fn set<T: StorableInTable>(&self, index: u32, element: T) -> Result<(), TableAccessError> {
|
||||||
let mut storage = self.storage.lock().unwrap();
|
let mut guard = self.storage.lock().unwrap();
|
||||||
match &mut *storage {
|
let (storage, _) = &mut *guard;
|
||||||
(TableStorage::Anyfunc(ref mut anyfunc_table), _) => {
|
T::wrap_self(element, storage, index)
|
||||||
match element {
|
|
||||||
Element::Anyfunc(anyfunc) => anyfunc_table.set(index, anyfunc),
|
|
||||||
// _ => panic!("wrong element type for anyfunc table"),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn anyfunc_direct_access_mut<F, R>(&self, f: F) -> R
|
pub(crate) fn anyfunc_direct_access_mut<F, R>(&self, f: F) -> R
|
||||||
|
Reference in New Issue
Block a user