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

@@ -8,12 +8,15 @@ use wasmtime_environ::Module;
use wasmtime_runtime::{Imports, InstanceHandle, VMFunctionBody};
use std::any::Any;
use std::cell::RefCell;
use std::cell::{RefCell, RefMut};
use std::collections::{HashMap, HashSet};
use std::rc::Rc;
pub fn create_handle(
use crate::runtime::SignatureRegistry;
pub(crate) fn create_handle(
module: Module,
signature_registry: Option<RefMut<dyn SignatureRegistry>>,
finished_functions: PrimaryMap<DefinedFuncIndex, *const VMFunctionBody>,
state: Box<dyn Any>,
) -> Result<InstanceHandle, Error> {
@@ -28,7 +31,19 @@ pub fn create_handle(
PrimaryMap::new(),
);
let data_initializers = Vec::new();
let signatures = PrimaryMap::new();
// Compute indices into the shared signature table.
let signatures = signature_registry
.and_then(|mut signature_registry| {
Some(
module
.signatures
.values()
.map(|sig| signature_registry.register_cranelift_signature(sig))
.collect::<PrimaryMap<_, _>>(),
)
})
.unwrap_or_else(|| PrimaryMap::new());
Ok(InstanceHandle::new(
Rc::new(module),

View File

@@ -17,12 +17,12 @@ use core::cmp;
use std::cell::RefCell;
use std::rc::Rc;
use crate::{Func, Trap, Val};
use crate::{Callable, FuncType, Store, Trap, Val};
use super::create_handle::create_handle;
struct TrampolineState {
func: Rc<RefCell<Func>>,
func: Rc<dyn Callable + 'static>,
trap: Option<Rc<RefCell<Trap>>>,
#[allow(dead_code)]
code_memory: CodeMemory,
@@ -45,15 +45,15 @@ unsafe extern "C" fn stub_fn(vmctx: *mut VMContext, call_id: u32, values_vec: *m
(args, signature.returns.len())
};
let func = instance
let mut returns = vec![Val::default(); returns_len];
let func = &instance
.host_state()
.downcast_mut::<TrampolineState>()
.expect("state")
.func
.borrow();
.func;
match func.call(&args) {
Ok(returns) => {
match func.call(&args, &mut returns) {
Ok(()) => {
for i in 0..returns_len {
// TODO check signature.returns[i].value_type ?
returns[i].write_value_to(values_vec.offset(i as isize));
@@ -188,8 +188,12 @@ fn make_trampoline(
.as_ptr()
}
pub fn create_handle_with_function(func: &Rc<RefCell<Func>>) -> Result<InstanceHandle, Error> {
let sig = func.borrow().r#type().get_cranelift_signature().clone();
pub fn create_handle_with_function(
ft: &FuncType,
func: &Rc<dyn Callable + 'static>,
store: &Rc<RefCell<Store>>,
) -> Result<InstanceHandle, Error> {
let sig = ft.get_cranelift_signature().clone();
let isa = {
let isa_builder =
@@ -229,7 +233,12 @@ pub fn create_handle_with_function(func: &Rc<RefCell<Func>>) -> Result<InstanceH
code_memory,
};
create_handle(module, finished_functions, Box::new(trampoline_state))
create_handle(
module,
Some(store.borrow_mut()),
finished_functions,
Box::new(trampoline_state),
)
}
/// We don't expect trampoline compilation to produce any relocations, so

View File

@@ -35,7 +35,8 @@ pub fn create_global(
},
initializer: cranelift_wasm::GlobalInit::Import, // TODO is it right?
};
let mut handle = create_handle(Module::new(), PrimaryMap::new(), Box::new(())).expect("handle");
let mut handle =
create_handle(Module::new(), None, PrimaryMap::new(), Box::new(())).expect("handle");
Ok((
wasmtime_runtime::Export::Global {
definition: definition.as_mut(),

View File

@@ -29,5 +29,5 @@ pub fn create_handle_with_memory(memory: &MemoryType) -> Result<InstanceHandle,
wasmtime_environ::Export::Memory(memory_id),
);
create_handle(module, PrimaryMap::new(), Box::new(()))
create_handle(module, None, PrimaryMap::new(), Box::new(()))
}

View File

@@ -5,6 +5,7 @@ mod create_handle;
mod func;
mod global;
mod memory;
mod table;
use failure::Error;
use std::cell::RefCell;
@@ -13,16 +14,19 @@ use std::rc::Rc;
use self::func::create_handle_with_function;
use self::global::create_global;
use self::memory::create_handle_with_memory;
use super::{Func, GlobalType, MemoryType, Val};
use self::table::create_handle_with_table;
use super::{Callable, FuncType, GlobalType, MemoryType, Store, TableType, Val};
pub use self::global::GlobalState;
pub fn generate_func_export(f: &Rc<RefCell<Func>>) -> Result<(), Error> {
let mut instance = create_handle_with_function(f)?;
pub fn generate_func_export(
ft: &FuncType,
func: &Rc<dyn Callable + 'static>,
store: &Rc<RefCell<Store>>,
) -> Result<(wasmtime_runtime::InstanceHandle, wasmtime_runtime::Export), Error> {
let mut instance = create_handle_with_function(ft, func, store)?;
let export = instance.lookup("trampoline").expect("trampoline export");
f.borrow_mut().anchor = Some((instance, export));
Ok(())
Ok((instance, export))
}
pub fn generate_global_export(
@@ -39,3 +43,11 @@ pub fn generate_memory_export(
let export = instance.lookup("memory").expect("memory export");
Ok((instance, export))
}
pub fn generate_table_export(
t: &TableType,
) -> Result<(wasmtime_runtime::InstanceHandle, wasmtime_runtime::Export), Error> {
let mut instance = create_handle_with_table(t)?;
let export = instance.lookup("table").expect("table export");
Ok((instance, export))
}

View File

@@ -0,0 +1,35 @@
use cranelift_entity::PrimaryMap;
use cranelift_wasm::TableElementType;
use failure::Error;
use wasmtime_environ::Module;
use wasmtime_runtime::InstanceHandle;
use super::create_handle::create_handle;
use crate::{TableType, ValType};
pub fn create_handle_with_table(table: &TableType) -> Result<InstanceHandle, Error> {
let mut module = Module::new();
let table = cranelift_wasm::Table {
minimum: table.limits().min(),
maximum: if table.limits().max() == std::u32::MAX {
None
} else {
Some(table.limits().max())
},
ty: match table.element() {
ValType::FuncRef => TableElementType::Func,
_ => TableElementType::Val(table.element().get_cranelift_type()),
},
};
let tunable = Default::default();
let table_plan = wasmtime_environ::TablePlan::for_table(table, &tunable);
let table_id = module.table_plans.push(table_plan);
module.exports.insert(
"table".to_string(),
wasmtime_environ::Export::Table(table_id),
);
create_handle(module, None, PrimaryMap::new(), Box::new(()))
}