2018-12-18 17:21:12 -08:00
|
|
|
use crate::webassembly::Instance;
|
2018-12-18 17:23:45 -08:00
|
|
|
use libc::{c_int, c_void};
|
2018-12-18 23:21:18 -08:00
|
|
|
use std::cell::UnsafeCell;
|
2018-12-18 17:21:12 -08:00
|
|
|
|
|
|
|
/// setjmp
|
2018-12-18 17:23:45 -08:00
|
|
|
pub extern "C" fn __setjmp(env_addr: u32, instance: &mut Instance) -> c_int {
|
2018-12-18 17:21:12 -08:00
|
|
|
debug!("emscripten::__setjmp (setjmp)");
|
|
|
|
unsafe {
|
2018-12-18 23:21:18 -08:00
|
|
|
// Rather than using the env as the holder of the jump address,
|
|
|
|
// we obscure that id so we are in complete control of it
|
|
|
|
let obscure_env = instance.memory_offset_addr(0, env_addr as usize) as *mut i8;
|
|
|
|
let jmp_buf: UnsafeCell<[c_int; 27]> = UnsafeCell::new([0; 27]);
|
|
|
|
let mut jumps = &mut instance.emscripten_data.as_mut().unwrap().jumps;
|
|
|
|
let result = setjmp(jmp_buf.get() as _);
|
|
|
|
*obscure_env = jumps.len() as _;
|
|
|
|
jumps.push(jmp_buf);
|
|
|
|
// We use the index of the jump as the jump buffer (env)
|
|
|
|
result
|
2018-12-18 17:21:12 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// longjmp
|
2018-12-18 17:23:45 -08:00
|
|
|
pub extern "C" fn __longjmp(env_addr: u32, val: c_int, instance: &mut Instance) -> ! {
|
2018-12-18 17:21:12 -08:00
|
|
|
debug!("emscripten::__longjmp (longjmp) {}", val);
|
|
|
|
unsafe {
|
2018-12-18 23:21:18 -08:00
|
|
|
let obscure_env = instance.memory_offset_addr(0, env_addr as usize) as *mut i8;
|
|
|
|
let mut jumps = &mut instance.emscripten_data.as_mut().unwrap().jumps;
|
|
|
|
let mut real_env = &jumps[*obscure_env as usize];
|
|
|
|
longjmp(real_env.get() as _, val)
|
2018-12-18 17:21:12 -08:00
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
extern "C" {
|
|
|
|
fn setjmp(env: *mut c_void) -> c_int;
|
|
|
|
fn longjmp(env: *mut c_void, val: c_int) -> !;
|
|
|
|
}
|