diff --git a/lib/runtime-core/src/state.rs b/lib/runtime-core/src/state.rs index 195303383..c9b2d8b98 100644 --- a/lib/runtime-core/src/state.rs +++ b/lib/runtime-core/src/state.rs @@ -329,10 +329,11 @@ impl InstanceImage { #[cfg(all(unix, target_arch = "x86_64"))] pub mod x64 { use super::*; - use crate::alternative_stack::run_on_alternative_stack; + use crate::alternative_stack::{catch_unsafe_unwind, run_on_alternative_stack}; use crate::structures::TypedIndex; use crate::types::LocalGlobalIndex; use crate::vm::Ctx; + use std::any::Any; use std::ops::Bound::Excluded; pub fn new_machine_state() -> MachineState { @@ -345,25 +346,13 @@ pub mod x64 { } } - pub unsafe fn invoke_call_return_on_stack_raw_image( - msm: &ModuleStateMap, - code_base: usize, - image_raw: Vec, - vmctx: &mut Ctx, - ) -> u64 { - use bincode::deserialize; - let image: InstanceImage = deserialize(&image_raw).unwrap(); - drop(image_raw); // free up memory - invoke_call_return_on_stack(msm, code_base, image, vmctx) - } - #[warn(unused_variables)] pub unsafe fn invoke_call_return_on_stack( msm: &ModuleStateMap, code_base: usize, image: InstanceImage, vmctx: &mut Ctx, - ) -> u64 { + ) -> Result> { let mut stack: Vec = vec![0; 1048576 * 8 / 8]; // 8MB stack let mut stack_offset: usize = stack.len(); @@ -523,10 +512,12 @@ pub mod x64 { drop(image); // free up host memory - run_on_alternative_stack( - stack.as_mut_ptr().offset(stack.len() as isize), - stack.as_mut_ptr().offset(stack_offset as isize), - ) + catch_unsafe_unwind(|| { + run_on_alternative_stack( + stack.as_mut_ptr().offset(stack.len() as isize), + stack.as_mut_ptr().offset(stack_offset as isize), + ) + }) } pub fn build_instance_image( diff --git a/lib/runtime-core/src/suspend.rs b/lib/runtime-core/src/suspend.rs index e3b133beb..e73695dc5 100644 --- a/lib/runtime-core/src/suspend.rs +++ b/lib/runtime-core/src/suspend.rs @@ -1,8 +1,7 @@ use crate::alternative_stack::begin_unsafe_unwind; use crate::import::{ImportObject, Namespace}; -use crate::trampoline::{CallContext, TrampolineBuffer, TrampolineBufferBuilder}; +use crate::trampoline::{CallContext, TrampolineBufferBuilder}; use crate::vm::Ctx; -use std::rc::Rc; use std::sync::atomic::{AtomicBool, Ordering}; static INTERRUPTED: AtomicBool = AtomicBool::new(false); @@ -19,40 +18,39 @@ pub fn get_and_reset_interrupted() -> bool { INTERRUPTED.swap(false, Ordering::SeqCst) } -struct ImportContext { - _trampolines: Rc, -} - -impl ImportContext { - fn new(trampolines: Rc) -> ImportContext { - ImportContext { - _trampolines: trampolines, - } - } -} - pub fn patch_import_object(x: &mut ImportObject) { - let mut builder = TrampolineBufferBuilder::new(); + struct Intrinsics { + suspend: fn(&mut Ctx), + check_interrupt: fn(&mut Ctx), + } - let idx_suspend = - builder.add_context_rsp_state_preserving_trampoline(suspend, ::std::ptr::null()); - let idx_check_interrupt = - builder.add_context_rsp_state_preserving_trampoline(check_interrupt, ::std::ptr::null()); - let trampolines = builder.build(); + lazy_static! { + static ref INTRINSICS: Intrinsics = { + let mut builder = TrampolineBufferBuilder::new(); + let idx_suspend = + builder.add_context_rsp_state_preserving_trampoline(suspend, ::std::ptr::null()); + let idx_check_interrupt = builder + .add_context_rsp_state_preserving_trampoline(check_interrupt, ::std::ptr::null()); + let trampolines = builder.build(); - let suspend_indirect: fn(&mut Ctx) = - unsafe { ::std::mem::transmute(trampolines.get_trampoline(idx_suspend)) }; - let check_interrupt_indirect: fn(&mut Ctx) = - unsafe { ::std::mem::transmute(trampolines.get_trampoline(idx_check_interrupt)) }; - - let trampolines = Rc::new(trampolines); - - // FIXME: Memory leak! - ::std::mem::forget(ImportContext::new(trampolines.clone())); + let ret = Intrinsics { + suspend: unsafe { ::std::mem::transmute(trampolines.get_trampoline(idx_suspend)) }, + check_interrupt: unsafe { + ::std::mem::transmute(trampolines.get_trampoline(idx_check_interrupt)) + }, + }; + ::std::mem::forget(trampolines); + ret + }; + } let mut ns = Namespace::new(); - ns.insert("suspend", func!(suspend_indirect)); - ns.insert("check_interrupt", func!(check_interrupt_indirect)); + + let suspend_fn = INTRINSICS.suspend; + let check_interrupt_fn = INTRINSICS.check_interrupt; + + ns.insert("suspend", func!(suspend_fn)); + ns.insert("check_interrupt", func!(check_interrupt_fn)); x.register("wasmer_suspend", ns); } @@ -97,9 +95,8 @@ unsafe fn do_suspend(ctx: &mut Ctx, mut stack: *const u64) -> ! { { use colored::*; - eprintln!("\n{}", "Suspending instance.".green().bold()); + eprintln!("{}", "Suspending instance.".green().bold()); } - es_image.print_backtrace_if_needed(); build_instance_image(ctx, es_image) }; diff --git a/src/bin/wasmer.rs b/src/bin/wasmer.rs index f8c2d5dbb..6fa95bea2 100644 --- a/src/bin/wasmer.rs +++ b/src/bin/wasmer.rs @@ -542,14 +542,13 @@ fn execute_wasm(options: &Run) -> Result<(), String> { let code_base = instance.module.runnable_module.get_code().unwrap().as_ptr() as usize; - catch_unsafe_unwind(|| { - invoke_call_return_on_stack( - &msm, - code_base, - image, - instance.context_mut(), - ); - }) + invoke_call_return_on_stack( + &msm, + code_base, + image, + instance.context_mut(), + ) + .map(|_| ()) } else { catch_unsafe_unwind(|| start_raw(instance.context_mut())) };