2019-01-24 05:49:34 +00:00
|
|
|
use super::env::get_emscripten_data;
|
2018-12-19 01:23:45 +00:00
|
|
|
use libc::{c_int, c_void};
|
2019-01-24 05:49:34 +00:00
|
|
|
use std::cell::UnsafeCell;
|
2019-01-23 07:27:13 +00:00
|
|
|
use wasmer_runtime_core::vm::Ctx;
|
2018-12-19 01:21:12 +00:00
|
|
|
|
|
|
|
/// setjmp
|
2019-02-09 21:58:05 +00:00
|
|
|
pub fn __setjmp(ctx: &mut Ctx, env_addr: u32) -> c_int {
|
2018-12-19 01:21:12 +00:00
|
|
|
debug!("emscripten::__setjmp (setjmp)");
|
2019-01-24 05:49:34 +00:00
|
|
|
unsafe {
|
2019-02-09 01:47:51 +00:00
|
|
|
// Rather than using the env as the holder of the jump buffer pointer,
|
|
|
|
// we use the environment address to store the index relative to jumps
|
|
|
|
// so the address of the jump it's outside the wasm memory itself.
|
|
|
|
let jump_index = emscripten_memory_pointer!(ctx.memory(0), env_addr) as *mut i8;
|
|
|
|
// We create the jump buffer outside of the wasm memory
|
|
|
|
let jump_buf: UnsafeCell<[u32; 27]> = UnsafeCell::new([0; 27]);
|
|
|
|
let jumps = &mut get_emscripten_data(ctx).jumps;
|
|
|
|
let result = setjmp(jump_buf.get() as _);
|
2019-02-09 21:58:05 +00:00
|
|
|
// We set the jump index to be the last 3value of jumps
|
2019-02-09 01:47:51 +00:00
|
|
|
*jump_index = jumps.len() as _;
|
|
|
|
// We hold the reference of the jump buffer
|
|
|
|
jumps.push(jump_buf);
|
|
|
|
result
|
2019-01-24 05:49:34 +00:00
|
|
|
}
|
2018-12-19 01:21:12 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/// longjmp
|
2019-02-01 01:44:57 +00:00
|
|
|
#[allow(unreachable_code)]
|
2019-02-09 21:58:05 +00:00
|
|
|
pub fn __longjmp(ctx: &mut Ctx, env_addr: u32, val: c_int) {
|
2019-01-24 05:49:34 +00:00
|
|
|
debug!("emscripten::__longjmp (longmp)");
|
|
|
|
unsafe {
|
|
|
|
// We retrieve the jump index from the env address
|
2019-01-24 21:04:12 +00:00
|
|
|
let jump_index = emscripten_memory_pointer!(ctx.memory(0), env_addr) as *mut i8;
|
2019-01-24 06:00:38 +00:00
|
|
|
let jumps = &mut get_emscripten_data(ctx).jumps;
|
2019-01-24 05:49:34 +00:00
|
|
|
// We get the real jump buffer from the jumps vector, using the retrieved index
|
2019-01-24 06:00:38 +00:00
|
|
|
let jump_buf = &jumps[*jump_index as usize];
|
2019-01-24 05:49:34 +00:00
|
|
|
longjmp(jump_buf.get() as _, val)
|
|
|
|
};
|
2018-12-19 01:21:12 +00:00
|
|
|
}
|
|
|
|
|
2019-04-06 21:32:21 +00:00
|
|
|
/// _longjmp
|
|
|
|
pub fn _longjmp(ctx: &mut Ctx, env_addr: i32, val: c_int) {
|
|
|
|
let val = if val == 0 {
|
|
|
|
1
|
|
|
|
} else {
|
|
|
|
val
|
|
|
|
};
|
|
|
|
get_emscripten_data(ctx).set_threw.as_ref().expect("set_threw is None").call(env_addr, val).expect("set_threw failed to call");
|
|
|
|
panic!("longjmp");
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2018-12-19 01:21:12 +00:00
|
|
|
extern "C" {
|
|
|
|
fn setjmp(env: *mut c_void) -> c_int;
|
|
|
|
fn longjmp(env: *mut c_void, val: c_int) -> !;
|
|
|
|
}
|