Table operation; refactor Callable

This commit is contained in:
Yury Delendik
2019-08-27 11:44:02 -05:00
committed by Dan Gohman
parent e60bf7f7e8
commit de1c0f63eb
17 changed files with 641 additions and 114 deletions

View File

@@ -1,14 +1,15 @@
use crate::callable::{Callable, WasmtimeFn};
use crate::callable::{Callable, NativeCallable, WasmtimeFn, WrappedCallable};
use crate::runtime::Store;
use crate::table_utils;
use crate::trampoline::{generate_global_export, generate_memory_export, generate_table_export};
use crate::trap::Trap;
use crate::types::{ExternType, FuncType, GlobalType, MemoryType, TableType, ValType};
use crate::values::Val;
use std::cell::RefCell;
use std::rc::Rc;
use std::result::Result;
use crate::trampoline::{generate_func_export, generate_global_export, generate_memory_export};
use wasmtime_runtime::InstanceHandle;
// Externals
pub enum Extern {
@@ -55,15 +56,10 @@ impl Extern {
pub(crate) fn get_wasmtime_export(&mut self) -> wasmtime_runtime::Export {
match self {
Extern::Func(f) => {
if f.borrow().anchor.is_none() {
generate_func_export(&f).expect("generate_func_export");
}
f.borrow().anchor.as_ref().unwrap().1.clone()
}
Extern::Func(f) => f.borrow().wasmtime_export().clone(),
Extern::Global(g) => g.borrow().wasmtime_export().clone(),
Extern::Memory(m) => m.borrow().wasmtime_export().clone(),
_ => unimplemented!("get_wasmtime_export"),
Extern::Table(t) => t.borrow().wasmtime_export().clone(),
}
}
@@ -73,53 +69,47 @@ impl Extern {
export: wasmtime_runtime::Export,
) -> Extern {
match export {
wasmtime_runtime::Export::Function {
address,
vmctx,
ref signature,
} => {
let ty = FuncType::from_cranelift_signature(signature.clone());
let callable = WasmtimeFn::new(store.clone(), signature.clone(), address, vmctx);
let mut f = Func::new(store, ty, Rc::new(callable));
f.anchor = Some((instance_handle, export.clone()));
Extern::Func(Rc::new(RefCell::new(f)))
}
wasmtime_runtime::Export::Function { .. } => Extern::Func(Rc::new(RefCell::new(
Func::from_wasmtime_function(export, store, instance_handle),
))),
wasmtime_runtime::Export::Memory { .. } => Extern::Memory(Rc::new(RefCell::new(
Memory::from_wasmtime_memory(export, store, instance_handle),
))),
wasmtime_runtime::Export::Global { .. } => Extern::Global(Rc::new(RefCell::new(
Global::from_wasmtime_global(export, store),
))),
wasmtime_runtime::Export::Table {
definition: _,
vmctx: _,
table,
} => {
let ty = TableType::from_cranelift_table(table.table.clone());
Extern::Table(Rc::new(RefCell::new(Table::new(store, ty))))
}
wasmtime_runtime::Export::Table { .. } => Extern::Table(Rc::new(RefCell::new(
Table::from_wasmtime_table(export, store, instance_handle),
))),
}
}
}
pub struct Func {
_store: Rc<RefCell<Store>>,
callable: Rc<dyn Callable + 'static>,
callable: Rc<dyn WrappedCallable + 'static>,
r#type: FuncType,
pub(crate) anchor: Option<(InstanceHandle, wasmtime_runtime::Export)>,
}
impl Func {
pub fn new(
store: Rc<RefCell<Store>>,
r#type: FuncType,
ty: FuncType,
callable: Rc<dyn Callable + 'static>,
) -> Self {
let callable = Rc::new(NativeCallable::new(callable, &ty, &store));
Func::from_wrapped(store, ty, callable)
}
fn from_wrapped(
store: Rc<RefCell<Store>>,
r#type: FuncType,
callable: Rc<dyn WrappedCallable + 'static>,
) -> Func {
Func {
_store: store,
callable,
r#type,
anchor: None,
}
}
@@ -127,6 +117,10 @@ impl Func {
&self.r#type
}
pub(crate) fn callable(&self) -> &Rc<dyn WrappedCallable + 'static> {
&self.callable
}
pub fn param_arity(&self) -> usize {
self.r#type.params().len()
}
@@ -135,15 +129,29 @@ impl Func {
self.r#type.results().len()
}
pub fn callable(&self) -> &(dyn Callable + 'static) {
self.callable.as_ref()
}
pub fn call(&self, params: &[Val]) -> Result<Box<[Val]>, Rc<RefCell<Trap>>> {
let mut results = vec![Val::default(); self.result_arity()];
self.callable.call(params, &mut results)?;
Ok(results.into_boxed_slice())
}
fn wasmtime_export(&self) -> &wasmtime_runtime::Export {
self.callable.wasmtime_export()
}
fn from_wasmtime_function(
export: wasmtime_runtime::Export,
store: Rc<RefCell<Store>>,
instance_handle: InstanceHandle,
) -> Self {
let ty = if let wasmtime_runtime::Export::Function { signature, .. } = &export {
FuncType::from_cranelift_signature(signature.clone())
} else {
panic!("expected function export")
};
let callable = WasmtimeFn::new(store.clone(), instance_handle, export.clone());
Func::from_wrapped(store, ty, Rc::new(callable))
}
}
pub struct Global {
@@ -234,15 +242,27 @@ impl Global {
}
pub struct Table {
_store: Rc<RefCell<Store>>,
store: Rc<RefCell<Store>>,
r#type: TableType,
#[allow(dead_code)]
wasmtime_handle: InstanceHandle,
wasmtime_export: wasmtime_runtime::Export,
}
impl Table {
pub fn new(store: Rc<RefCell<Store>>, r#type: TableType) -> Table {
pub fn new(store: Rc<RefCell<Store>>, r#type: TableType, _init: Val) -> Table {
match r#type.element() {
ValType::FuncRef => (),
_ => panic!("table is not for funcref"),
}
// TODO implement _init initialization
let (wasmtime_handle, wasmtime_export) =
generate_table_export(&r#type).expect("generated table");
Table {
_store: store,
store,
r#type,
wasmtime_handle,
wasmtime_export,
}
}
@@ -250,20 +270,54 @@ impl Table {
&self.r#type
}
pub fn get(&self, _index: u32) -> Val {
unimplemented!("Table::get")
fn wasmtime_table_definition(&self) -> *mut wasmtime_runtime::VMTableDefinition {
match self.wasmtime_export {
wasmtime_runtime::Export::Table { definition, .. } => definition,
_ => panic!("global definition not found"),
}
}
pub fn set(&self, _index: u32, _val: &Val) -> usize {
unimplemented!("Table::set")
pub fn get(&self, index: u32) -> Val {
let definition = self.wasmtime_table_definition();
unsafe { table_utils::get_item(definition, &self.store, index) }
}
pub fn set(&self, index: u32, val: Val) -> bool {
let definition = self.wasmtime_table_definition();
unsafe { table_utils::set_item(definition, &self.store, index, val) }
}
pub fn size(&self) -> u32 {
unimplemented!("Table::size")
let definition = self.wasmtime_table_definition();
unsafe { table_utils::get_size(definition) }
}
pub fn grow(&mut self, _delta: u32) -> bool {
unimplemented!("Table::grow")
pub fn grow(&mut self, delta: u32, init: Val) -> bool {
let definition = self.wasmtime_table_definition();
unsafe { table_utils::grow_table(definition, &self.r#type, &self.store, delta, init) }
}
pub(crate) fn wasmtime_export(&self) -> &wasmtime_runtime::Export {
&self.wasmtime_export
}
pub(crate) fn from_wasmtime_table(
export: wasmtime_runtime::Export,
store: Rc<RefCell<Store>>,
instance_handle: wasmtime_runtime::InstanceHandle,
) -> Table {
let table = if let wasmtime_runtime::Export::Table { ref table, .. } = export {
table
} else {
panic!("wasmtime export is not table")
};
let ty = TableType::from_cranelift_table(table.table.clone());
Table {
store,
r#type: ty,
wasmtime_handle: instance_handle,
wasmtime_export: export,
}
}
}