diff --git a/lib/clif-backend/src/call/mod.rs b/lib/clif-backend/src/call/mod.rs index 9c87fa8c9..d2368da9d 100644 --- a/lib/clif-backend/src/call/mod.rs +++ b/lib/clif-backend/src/call/mod.rs @@ -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, @@ -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) -} \ No newline at end of file +} diff --git a/lib/clif-backend/src/call/recovery.rs b/lib/clif-backend/src/call/recovery.rs index 3733dc51a..e186dfe6f 100644 --- a/lib/clif-backend/src/call/recovery.rs +++ b/lib/clif-backend/src/call/recovery.rs @@ -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; diff --git a/lib/clif-backend/src/lib.rs b/lib/clif-backend/src/lib.rs index 5899dd51f..7fefcf728 100644 --- a/lib/clif-backend/src/lib.rs +++ b/lib/clif-backend/src/lib.rs @@ -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, diff --git a/lib/clif-backend/src/module.rs b/lib/clif-backend/src/module.rs index 6fbb525da..886da3f76 100644 --- a/lib/clif-backend/src/module.rs +++ b/lib/clif-backend/src/module.rs @@ -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) } } diff --git a/lib/runtime/src/backend.rs b/lib/runtime/src/backend.rs index 3cf7b0945..e4372f6f3 100644 --- a/lib/runtime/src/backend.rs +++ b/lib/runtime/src/backend.rs @@ -1,8 +1,8 @@ use crate::{ + backing::ImportBacking, error::CompileResult, error::RuntimeResult, module::ModuleInner, - backing::ImportBacking, types::{FuncIndex, LocalFuncIndex, Value}, vm, }; diff --git a/lib/runtime/src/instance.rs b/lib/runtime/src/instance.rs index 760ad2243..97b7e3470 100644 --- a/lib/runtime/src/instance.rs +++ b/lib/runtime/src/instance.rs @@ -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]; ( diff --git a/lib/runtime/src/module.rs b/lib/runtime/src/module.rs index 2ccf5f7c0..dceea000b 100644 --- a/lib/runtime/src/module.rs +++ b/lib/runtime/src/module.rs @@ -19,6 +19,7 @@ use std::rc::Rc; pub struct ModuleInner { pub func_resolver: Box, pub protected_caller: Box, + // This are strictly local and the typsystem ensures that. pub memories: Map, pub globals: Map,