transition to protected_caller

This commit is contained in:
Lachlan Sneff 2019-01-18 14:30:15 -08:00
parent 539db9f577
commit 9ed0018045
7 changed files with 69 additions and 47 deletions

View File

@ -2,17 +2,17 @@ mod recovery;
mod sighandler;
use crate::call::recovery::call_protected;
use hashbrown::HashSet;
use libffi::high::{arg as libffi_arg, call as libffi_call, CodePtr};
use std::iter;
use wasmer_runtime::{
backend::{Token, ProtectedCaller},
types::{FuncIndex, Value, Type, FuncSig, LocalOrImport},
module::ModuleInner,
error::{RuntimeResult},
backend::{ProtectedCaller, Token},
error::RuntimeResult,
export::Context,
module::{ExportIndex, ModuleInner},
types::{FuncIndex, FuncSig, LocalOrImport, Type, Value},
vm::{self, ImportBacking},
};
use libffi::high::{arg as libffi_arg, call as libffi_call, CodePtr};
use hashbrown::HashSet;
use std::iter;
pub struct Caller {
func_export_set: HashSet<FuncIndex>,
@ -20,7 +20,14 @@ pub struct Caller {
impl Caller {
pub fn new(module: &ModuleInner) -> Self {
let mut func_export_set = HashSet::new();
for export_index in module.exports.values() {
if let ExportIndex::Func(func_index) = export_index {
func_export_set.insert(*func_index);
}
}
Self { func_export_set }
}
}
@ -66,7 +73,7 @@ impl ProtectedCaller for Caller {
call_protected(|| {
// Only supports zero or one return values for now.
// To support multiple returns, we will have to
// To support multiple returns, we will have to
// generate trampolines instead of using libffi.
match signature.returns.first() {
Some(ty) => {
@ -77,7 +84,7 @@ impl ProtectedCaller for Caller {
Type::F64 => Value::F64(unsafe { libffi_call(code_ptr, &libffi_args) }),
};
returns[0] = val;
},
}
// call with no returns
None => unsafe {
libffi_call::<()>(code_ptr, &libffi_args);
@ -87,7 +94,6 @@ impl ProtectedCaller for Caller {
}
}
fn get_func_from_index<'a>(
module: &'a ModuleInner,
import_backing: &ImportBacking,
@ -99,17 +105,15 @@ fn get_func_from_index<'a>(
.expect("broken invariant, incorrect func index");
let (func_ptr, ctx) = match func_index.local_or_import(module) {
LocalOrImport::Local(local_func_index) => {
(
module
.func_resolver
.get(&module, local_func_index)
.expect("broken invariant, func resolver not synced with module.exports")
.cast()
.as_ptr() as *const _,
Context::Internal,
)
}
LocalOrImport::Local(local_func_index) => (
module
.func_resolver
.get(&module, local_func_index)
.expect("broken invariant, func resolver not synced with module.exports")
.cast()
.as_ptr() as *const _,
Context::Internal,
),
LocalOrImport::Import(imported_func_index) => {
let imported_func = import_backing.imported_func(imported_func_index);
(
@ -122,4 +126,4 @@ fn get_func_from_index<'a>(
let signature = module.sig_registry.lookup_func_sig(sig_index);
(func_ptr, ctx, signature)
}
}

View File

@ -4,14 +4,12 @@
//! are very special, the async signal unsafety of Rust's TLS implementation generally does not affect the correctness here
//! unless you have memory unsafety elsewhere in your code.
use wasmer_runtime::{
error::{RuntimeError, RuntimeResult},
};
use crate::call::sighandler::install_sighandler;
use nix::libc::siginfo_t;
use nix::sys::signal::{Signal, SIGBUS, SIGFPE, SIGILL, SIGSEGV};
use std::cell::{Cell, UnsafeCell};
use std::sync::Once;
use wasmer_runtime::error::{RuntimeError, RuntimeResult};
extern "C" {
pub fn setjmp(env: *mut ::nix::libc::c_void) -> ::nix::libc::c_int;

View File

@ -1,11 +1,11 @@
// pub mod codegen;
mod call;
mod func_env;
mod libcalls;
mod module;
mod module_env;
mod relocation;
mod resolver;
mod call;
use cranelift_codegen::{
isa,

View File

@ -1,4 +1,4 @@
use crate::resolver::FuncResolverBuilder;
use crate::{call::Caller, resolver::FuncResolverBuilder};
use cranelift_codegen::{ir, isa};
use cranelift_entity::EntityRef;
use cranelift_wasm;
@ -8,20 +8,21 @@ use std::{
ptr::NonNull,
};
use wasmer_runtime::{
backend::FuncResolver,
backend::SigRegistry,
error::CompileResult,
backend::{FuncResolver, ProtectedCaller, Token},
error::{CompileResult, RuntimeResult},
module::ModuleInner,
structures::{Map, TypedIndex},
types::{
FuncIndex, FuncSig, GlobalIndex, LocalFuncIndex, MemoryIndex, SigIndex, TableIndex, Type,
Value,
},
vm,
vm::{self, ImportBacking},
};
struct PlaceholderFuncResolver;
struct Placeholder;
impl FuncResolver for PlaceholderFuncResolver {
impl FuncResolver for Placeholder {
fn get(
&self,
_module: &ModuleInner,
@ -31,6 +32,21 @@ impl FuncResolver for PlaceholderFuncResolver {
}
}
impl ProtectedCaller for Placeholder {
fn call(
&self,
_module: &ModuleInner,
_func_index: FuncIndex,
_params: &[Value],
_returns: &mut [Value],
_import_backing: &ImportBacking,
_vmctx: *mut vm::Ctx,
_: Token,
) -> RuntimeResult<()> {
Ok(())
}
}
/// This contains all of the items in a `ModuleInner` except the `func_resolver`.
pub struct Module {
pub module: ModuleInner,
@ -41,7 +57,9 @@ impl Module {
Self {
module: ModuleInner {
// this is a placeholder
func_resolver: Box::new(PlaceholderFuncResolver),
func_resolver: Box::new(Placeholder),
protected_caller: Box::new(Placeholder),
memories: Map::new(),
globals: Map::new(),
tables: Map::new(),
@ -78,6 +96,9 @@ impl Module {
let func_resolver_builder = FuncResolverBuilder::new(isa, functions)?;
self.module.func_resolver = Box::new(func_resolver_builder.finalize()?);
self.module.protected_caller = Box::new(Caller::new(&self.module));
Ok(self.module)
}
}

View File

@ -1,8 +1,8 @@
use crate::{
backing::ImportBacking,
error::CompileResult,
error::RuntimeResult,
module::ModuleInner,
backing::ImportBacking,
types::{FuncIndex, LocalFuncIndex, Value},
vm,
};

View File

@ -13,8 +13,8 @@ use crate::{
},
vm,
};
use std::rc::Rc;
use std::mem;
use std::rc::Rc;
pub(crate) struct InstanceInner {
#[allow(dead_code)]
@ -201,17 +201,15 @@ impl InstanceInner {
.expect("broken invariant, incorrect func index");
let (func_ptr, ctx) = match func_index.local_or_import(module) {
LocalOrImport::Local(local_func_index) => {
(
module
.func_resolver
.get(&module, local_func_index)
.expect("broken invariant, func resolver not synced with module.exports")
.cast()
.as_ptr() as *const _,
Context::Internal,
)
}
LocalOrImport::Local(local_func_index) => (
module
.func_resolver
.get(&module, local_func_index)
.expect("broken invariant, func resolver not synced with module.exports")
.cast()
.as_ptr() as *const _,
Context::Internal,
),
LocalOrImport::Import(imported_func_index) => {
let imported_func = &self.import_backing.functions[imported_func_index];
(

View File

@ -19,6 +19,7 @@ use std::rc::Rc;
pub struct ModuleInner {
pub func_resolver: Box<dyn FuncResolver>,
pub protected_caller: Box<dyn ProtectedCaller>,
// This are strictly local and the typsystem ensures that.
pub memories: Map<LocalMemoryIndex, Memory>,
pub globals: Map<LocalGlobalIndex, Global>,