Wrap alternative stack functions properly.

This commit is contained in:
losfair
2019-06-26 20:44:51 +08:00
parent 73ca597d73
commit a792ac6a48
6 changed files with 107 additions and 56 deletions

View File

@ -0,0 +1,48 @@
mod raw {
extern "C" {
pub fn run_on_alternative_stack(
stack_end: *mut u64,
stack_begin: *mut u64,
userdata_arg2: *mut u8,
) -> u64;
}
}
pub(crate) unsafe fn run_on_alternative_stack(stack_end: *mut u64, stack_begin: *mut u64) -> u64 {
raw::run_on_alternative_stack(stack_end, stack_begin, ::std::ptr::null_mut())
}
pub fn allocate_and_run<R, F: FnOnce() -> R>(size: usize, f: F) -> R {
struct Context<F: FnOnce() -> R, R> {
f: Option<F>,
ret: Option<R>,
}
extern "C" fn invoke<F: FnOnce() -> R, R>(_: u64, _: u64, ctx: &mut Context<F, R>) {
let f = ctx.f.take().unwrap();
ctx.ret = Some(f());
}
unsafe {
let mut ctx = Context {
f: Some(f),
ret: None,
};
assert!(size % 16 == 0);
assert!(size >= 4096);
let mut stack: Vec<u64> = vec![0; size / 8];
let mut end_offset = stack.len();
stack[end_offset - 4] = invoke::<F, R> as usize as u64;
let stack_begin = stack.as_mut_ptr().offset((end_offset - 4 - 6) as isize);
let stack_end = stack.as_mut_ptr().offset(end_offset as isize);
raw::run_on_alternative_stack(
stack_end,
stack_begin,
&mut ctx as *mut Context<F, R> as *mut u8,
);
ctx.ret.take().unwrap()
}
}

View File

@ -43,6 +43,8 @@ pub mod vm;
pub mod vmcalls;
#[cfg(all(unix, target_arch = "x86_64"))]
pub use trampoline_x64 as trampoline;
#[cfg(all(unix, target_arch = "x86_64"))]
pub mod alternative_stack;
pub mod state;
#[cfg(all(unix, target_arch = "x86_64"))]
pub mod suspend;

View File

@ -321,10 +321,8 @@ impl ExecutionStateImage {
#[cfg(all(unix, target_arch = "x86_64"))]
pub mod x64 {
extern "C" {
fn run_on_wasm_stack(stack_end: *mut u64, stack_begin: *mut u64) -> u64;
}
use super::*;
use crate::alternative_stack::run_on_alternative_stack;
use crate::structures::TypedIndex;
use crate::types::LocalGlobalIndex;
use crate::vm::Ctx;
@ -515,7 +513,7 @@ pub mod x64 {
image.globals[i];
}
run_on_wasm_stack(
run_on_alternative_stack(
stack.as_mut_ptr().offset(stack.len() as isize),
stack.as_mut_ptr().offset(stack_offset as isize),
)