Skip to content

Commit

Permalink
Improved documentation of setjmp/longjmp
Browse files Browse the repository at this point in the history
  • Loading branch information
syrusakbary committed Dec 19, 2018
1 parent db93d26 commit a912c14
Showing 1 changed file with 16 additions and 11 deletions.
27 changes: 16 additions & 11 deletions src/apis/emscripten/jmp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,18 @@ use std::cell::UnsafeCell;
pub extern "C" fn __setjmp(env_addr: u32, instance: &mut Instance) -> c_int {
debug!("emscripten::__setjmp (setjmp)");
unsafe {
// 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]);
// 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 = instance.memory_offset_addr(0, env_addr as usize) as *mut i8;
// We create the jump buffer outside of the wasm memory
let jump_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)
let result = setjmp(jump_buf.get() as _);
// We set the jump index to be the last value of jumps
*jump_index = jumps.len() as _;
// We hold the reference of the jump buffer
jumps.push(jump_buf);
result
}
}
Expand All @@ -23,10 +26,12 @@ pub extern "C" fn __setjmp(env_addr: u32, instance: &mut Instance) -> c_int {
pub extern "C" fn __longjmp(env_addr: u32, val: c_int, instance: &mut Instance) -> ! {
debug!("emscripten::__longjmp (longjmp) {}", val);
unsafe {
let obscure_env = instance.memory_offset_addr(0, env_addr as usize) as *mut i8;
// We retrieve the jump index from the env address
let jump_index = 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)
// We get the real jump buffer from the jumps vector, using the retrieved index
let mut jump_buf = &jumps[*jump_index as usize];
longjmp(jump_buf.get() as _, val)
};
}

Expand Down

0 comments on commit a912c14

Please sign in to comment.