wasmer_emscripten/
jmp.rs

1use super::env::get_emscripten_funcs;
2use super::process::abort_with_message;
3use libc::c_int;
4// use std::cell::UnsafeCell;
5use crate::EmEnv;
6use std::error::Error;
7use std::fmt;
8use wasmer::FunctionEnvMut;
9
10/// setjmp
11pub fn __setjmp(ctx: FunctionEnvMut<EmEnv>, _env_addr: u32) -> c_int {
12    debug!("emscripten::__setjmp (setjmp)");
13    abort_with_message(ctx, "missing function: _setjmp");
14    unreachable!()
15    // unsafe {
16    //     // Rather than using the env as the holder of the jump buffer pointer,
17    //     // we use the environment address to store the index relative to jumps
18    //     // so the address of the jump it's outside the wasm memory itself.
19    //     let jump_index = emscripten_memory_pointer!(ctx.memory(0), env_addr) as *mut i8;
20    //     // We create the jump buffer outside of the wasm memory
21    //     let jump_buf: UnsafeCell<[u32; 27]> = UnsafeCell::new([0; 27]);
22    //     let jumps = &mut get_emscripten_data(&ctx).jumps;
23    //     let result = setjmp(jump_buf.get() as _);
24    //     // We set the jump index to be the last 3value of jumps
25    //     *jump_index = jumps.len() as _;
26    //     // We hold the reference of the jump buffer
27    //     jumps.push(jump_buf);
28    //     result
29    // }
30}
31
32/// longjmp
33#[allow(unreachable_code)]
34pub fn __longjmp(ctx: FunctionEnvMut<EmEnv>, _env_addr: u32, _val: c_int) {
35    debug!("emscripten::__longjmp (longmp)");
36    abort_with_message(ctx, "missing function: _longjmp");
37    // unsafe {
38    //     // We retrieve the jump index from the env address
39    //     let jump_index = emscripten_memory_pointer!(ctx.memory(0), env_addr) as *mut i8;
40    //     let jumps = &mut get_emscripten_data(&ctx).jumps;
41    //     // We get the real jump buffer from the jumps vector, using the retrieved index
42    //     let jump_buf = &jumps[*jump_index as usize];
43    //     longjmp(jump_buf.get() as _, val)
44    // };
45}
46
47#[derive(Copy, Clone, Debug)]
48pub struct LongJumpRet;
49
50impl fmt::Display for LongJumpRet {
51    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
52        write!(f, "LongJumpRet")
53    }
54}
55
56impl Error for LongJumpRet {}
57
58/// _longjmp
59// This function differs from the js implementation, it should return Result<(), &'static str>
60#[allow(unreachable_code)]
61pub fn _longjmp(
62    mut ctx: FunctionEnvMut<EmEnv>,
63    env_addr: i32,
64    val: c_int,
65) -> Result<(), LongJumpRet> {
66    let val = if val == 0 { 1 } else { val };
67    let threw = get_emscripten_funcs(&ctx)
68        .set_threw_ref()
69        .expect("set_threw is None")
70        .clone();
71    threw
72        .call(&mut ctx, env_addr, val)
73        .expect("set_threw failed to call");
74    Err(LongJumpRet)
75}
76
77// extern "C" {
78//     fn setjmp(env: *mut c_void) -> c_int;
79//     fn longjmp(env: *mut c_void, val: c_int) -> !;
80// }