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; mod sighandler;
use crate::call::recovery::call_protected; 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::{ use wasmer_runtime::{
backend::{Token, ProtectedCaller}, backend::{ProtectedCaller, Token},
types::{FuncIndex, Value, Type, FuncSig, LocalOrImport}, error::RuntimeResult,
module::ModuleInner,
error::{RuntimeResult},
export::Context, export::Context,
module::{ExportIndex, ModuleInner},
types::{FuncIndex, FuncSig, LocalOrImport, Type, Value},
vm::{self, ImportBacking}, vm::{self, ImportBacking},
}; };
use libffi::high::{arg as libffi_arg, call as libffi_call, CodePtr};
use hashbrown::HashSet;
use std::iter;
pub struct Caller { pub struct Caller {
func_export_set: HashSet<FuncIndex>, func_export_set: HashSet<FuncIndex>,
@ -20,7 +20,14 @@ pub struct Caller {
impl Caller { impl Caller {
pub fn new(module: &ModuleInner) -> Self { 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 }
} }
} }
@ -77,7 +84,7 @@ impl ProtectedCaller for Caller {
Type::F64 => Value::F64(unsafe { libffi_call(code_ptr, &libffi_args) }), Type::F64 => Value::F64(unsafe { libffi_call(code_ptr, &libffi_args) }),
}; };
returns[0] = val; returns[0] = val;
}, }
// call with no returns // call with no returns
None => unsafe { None => unsafe {
libffi_call::<()>(code_ptr, &libffi_args); libffi_call::<()>(code_ptr, &libffi_args);
@ -87,7 +94,6 @@ impl ProtectedCaller for Caller {
} }
} }
fn get_func_from_index<'a>( fn get_func_from_index<'a>(
module: &'a ModuleInner, module: &'a ModuleInner,
import_backing: &ImportBacking, import_backing: &ImportBacking,
@ -99,17 +105,15 @@ fn get_func_from_index<'a>(
.expect("broken invariant, incorrect func index"); .expect("broken invariant, incorrect func index");
let (func_ptr, ctx) = match func_index.local_or_import(module) { let (func_ptr, ctx) = match func_index.local_or_import(module) {
LocalOrImport::Local(local_func_index) => { LocalOrImport::Local(local_func_index) => (
( module
module .func_resolver
.func_resolver .get(&module, local_func_index)
.get(&module, local_func_index) .expect("broken invariant, func resolver not synced with module.exports")
.expect("broken invariant, func resolver not synced with module.exports") .cast()
.cast() .as_ptr() as *const _,
.as_ptr() as *const _, Context::Internal,
Context::Internal, ),
)
}
LocalOrImport::Import(imported_func_index) => { LocalOrImport::Import(imported_func_index) => {
let imported_func = import_backing.imported_func(imported_func_index); let imported_func = import_backing.imported_func(imported_func_index);
( (

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 //! 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. //! unless you have memory unsafety elsewhere in your code.
use wasmer_runtime::{
error::{RuntimeError, RuntimeResult},
};
use crate::call::sighandler::install_sighandler; use crate::call::sighandler::install_sighandler;
use nix::libc::siginfo_t; use nix::libc::siginfo_t;
use nix::sys::signal::{Signal, SIGBUS, SIGFPE, SIGILL, SIGSEGV}; use nix::sys::signal::{Signal, SIGBUS, SIGFPE, SIGILL, SIGSEGV};
use std::cell::{Cell, UnsafeCell}; use std::cell::{Cell, UnsafeCell};
use std::sync::Once; use std::sync::Once;
use wasmer_runtime::error::{RuntimeError, RuntimeResult};
extern "C" { extern "C" {
pub fn setjmp(env: *mut ::nix::libc::c_void) -> ::nix::libc::c_int; pub fn setjmp(env: *mut ::nix::libc::c_void) -> ::nix::libc::c_int;

View File

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

View File

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

View File

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

View File

@ -13,8 +13,8 @@ use crate::{
}, },
vm, vm,
}; };
use std::rc::Rc;
use std::mem; use std::mem;
use std::rc::Rc;
pub(crate) struct InstanceInner { pub(crate) struct InstanceInner {
#[allow(dead_code)] #[allow(dead_code)]
@ -201,17 +201,15 @@ impl InstanceInner {
.expect("broken invariant, incorrect func index"); .expect("broken invariant, incorrect func index");
let (func_ptr, ctx) = match func_index.local_or_import(module) { let (func_ptr, ctx) = match func_index.local_or_import(module) {
LocalOrImport::Local(local_func_index) => { LocalOrImport::Local(local_func_index) => (
( module
module .func_resolver
.func_resolver .get(&module, local_func_index)
.get(&module, local_func_index) .expect("broken invariant, func resolver not synced with module.exports")
.expect("broken invariant, func resolver not synced with module.exports") .cast()
.cast() .as_ptr() as *const _,
.as_ptr() as *const _, Context::Internal,
Context::Internal, ),
)
}
LocalOrImport::Import(imported_func_index) => { LocalOrImport::Import(imported_func_index) => {
let imported_func = &self.import_backing.functions[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 struct ModuleInner {
pub func_resolver: Box<dyn FuncResolver>, pub func_resolver: Box<dyn FuncResolver>,
pub protected_caller: Box<dyn ProtectedCaller>, pub protected_caller: Box<dyn ProtectedCaller>,
// This are strictly local and the typsystem ensures that. // This are strictly local and the typsystem ensures that.
pub memories: Map<LocalMemoryIndex, Memory>, pub memories: Map<LocalMemoryIndex, Memory>,
pub globals: Map<LocalGlobalIndex, Global>, pub globals: Map<LocalGlobalIndex, Global>,