diff --git a/lib/emscripten/src/jmp.rs b/lib/emscripten/src/jmp.rs index c5b54f02b..aa9367470 100644 --- a/lib/emscripten/src/jmp.rs +++ b/lib/emscripten/src/jmp.rs @@ -37,6 +37,18 @@ pub fn __longjmp(ctx: &mut Ctx, env_addr: u32, val: c_int) { }; } +/// _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"); +} + + extern "C" { fn setjmp(env: *mut c_void) -> c_int; fn longjmp(env: *mut c_void, val: c_int) -> !; diff --git a/lib/emscripten/src/lib.rs b/lib/emscripten/src/lib.rs index 09493c813..1ae84c82d 100644 --- a/lib/emscripten/src/lib.rs +++ b/lib/emscripten/src/lib.rs @@ -127,6 +127,10 @@ pub struct EmscriptenData<'a> { pub dyn_call_vijj: Option>, pub dyn_call_viidii: Option>, pub temp_ret_0: i32, + + pub stack_save: Option>, + pub stack_restore: Option>, + pub set_threw: Option>, } impl<'a> EmscriptenData<'a> { @@ -186,6 +190,10 @@ impl<'a> EmscriptenData<'a> { let dyn_call_vijj = instance.func("dynCall_vijj").ok(); let dyn_call_viidii = instance.func("dynCall_viidii").ok(); + let stack_save = instance.func("stackSave").ok(); + let stack_restore = instance.func("stackRestore").ok(); + let set_threw = instance.func("_setThrew").ok(); + EmscriptenData { malloc, free, @@ -238,6 +246,10 @@ impl<'a> EmscriptenData<'a> { dyn_call_vijj, dyn_call_viidii, temp_ret_0: 0, + + stack_save, + stack_restore, + set_threw } } } @@ -650,7 +662,8 @@ pub fn generate_emscripten_env(globals: &mut EmscriptenGlobals) -> ImportObject // Jump "__setjmp" => func!(crate::jmp::__setjmp), "__longjmp" => func!(crate::jmp::__longjmp), - "_longjmp" => func!(crate::jmp::__longjmp), + "_longjmp" => func!(crate::jmp::_longjmp), + "_emscripten_longjmp" => func!(crate::jmp::_longjmp), // Bitwise "_llvm_bswap_i64" => func!(crate::bitwise::_llvm_bswap_i64),