Improved Table API to matching Memory API

This commit is contained in:
Syrus
2020-06-03 13:51:26 -07:00
parent b3775ed97d
commit f6fd628953
2 changed files with 24 additions and 5 deletions

View File

@@ -6,6 +6,11 @@ use crate::RuntimeError;
use crate::TableType; use crate::TableType;
use wasmer_runtime::{Export, ExportTable, Table as RuntimeTable, VMCallerCheckedAnyfunc}; use wasmer_runtime::{Export, ExportTable, Table as RuntimeTable, VMCallerCheckedAnyfunc};
/// The `Table` struct is an array-like structure representing a WebAssembly Table,
/// which stores function references.
///
/// A table created by the host or in WebAssembly code will be accessible and
/// mutable from both host and WebAssembly.
#[derive(Clone)] #[derive(Clone)]
pub struct Table { pub struct Table {
store: Store, store: Store,
@@ -23,6 +28,9 @@ fn set_table_item(
} }
impl Table { impl Table {
/// Creates a new `Table` with the provided `TableType` definition
/// and an indicated `init` value that will be set to all the elements
/// in the table.
pub fn new(store: &Store, ty: TableType, init: Val) -> Result<Table, RuntimeError> { pub fn new(store: &Store, ty: TableType, init: Val) -> Result<Table, RuntimeError> {
let item = init.into_checked_anyfunc(store)?; let item = init.into_checked_anyfunc(store)?;
let tunables = store.engine().tunables(); let tunables = store.engine().tunables();
@@ -50,6 +58,7 @@ impl Table {
unsafe { &*self.exported.from } unsafe { &*self.exported.from }
} }
/// Gets the underlying [`TableType`].
pub fn ty(&self) -> &TableType { pub fn ty(&self) -> &TableType {
&self.exported.plan().table &self.exported.plan().table
} }
@@ -58,28 +67,35 @@ impl Table {
&self.store &self.store
} }
/// Retrieves an element of the table at the provided `index`.
pub fn get(&self, index: u32) -> Option<Val> { pub fn get(&self, index: u32) -> Option<Val> {
let item = self.table().get(index)?; let item = self.table().get(index)?;
Some(ValAnyFunc::from_checked_anyfunc(item, &self.store)) Some(ValAnyFunc::from_checked_anyfunc(item, &self.store))
} }
/// Sets an element `val` in the Table at the provided `index`.
pub fn set(&self, index: u32, val: Val) -> Result<(), RuntimeError> { pub fn set(&self, index: u32, val: Val) -> Result<(), RuntimeError> {
let item = val.into_checked_anyfunc(&self.store)?; let item = val.into_checked_anyfunc(&self.store)?;
set_table_item(self.table(), index, item) set_table_item(self.table(), index, item)
} }
/// Retrieves the size of the `Table` (in elements)
pub fn size(&self) -> u32 { pub fn size(&self) -> u32 {
self.table().size() self.table().size()
} }
/// Grows the size of the `Table` by `delta`, initializating
/// the elements with the provided `init` value.
///
/// It returns the previous size of the `Table` in case is able
/// to grow the Table successfully.
pub fn grow(&self, delta: u32, init: Val) -> Result<u32, RuntimeError> { pub fn grow(&self, delta: u32, init: Val) -> Result<u32, RuntimeError> {
let item = init.into_checked_anyfunc(&self.store)?; let item = init.into_checked_anyfunc(&self.store)?;
let table = self.table(); let table = self.table();
match table.grow(delta) { match table.grow(delta) {
Some(len) => { Some(len) => {
for i in 0..delta { for i in 0..delta {
let i = len - (delta - i); set_table_item(table, len + i, item.clone())?;
set_table_item(table, i, item.clone())?;
} }
Ok(len) Ok(len)
} }
@@ -90,6 +106,8 @@ impl Table {
} }
} }
/// Copies the `len` elements of `src_table` starting at `src_index`
/// to the destination table `dst_table` at index `dst_index`.
pub fn copy( pub fn copy(
dst_table: &Table, dst_table: &Table,
dst_index: u32, dst_index: u32,

View File

@@ -59,9 +59,10 @@ impl Table {
/// Grow table by the specified amount of elements. /// Grow table by the specified amount of elements.
/// ///
/// Returns `None` if table can't be grown by the specified amount /// Returns `None` if table can't be grown by the specified amount
/// of elements. /// of elements, otherwise returns the previous size of the table.
pub fn grow(&self, delta: u32) -> Option<u32> { pub fn grow(&self, delta: u32) -> Option<u32> {
let new_len = self.size().checked_add(delta)?; let size = self.size();
let new_len = size.checked_add(delta)?;
if self.maximum.map_or(false, |max| new_len > max) { if self.maximum.map_or(false, |max| new_len > max) {
return None; return None;
} }
@@ -69,7 +70,7 @@ impl Table {
usize::try_from(new_len).unwrap(), usize::try_from(new_len).unwrap(),
VMCallerCheckedAnyfunc::default(), VMCallerCheckedAnyfunc::default(),
); );
Some(new_len) Some(size)
} }
/// Get reference to the specified element. /// Get reference to the specified element.