Skip to content

Using rust with wasm error handling #19612

Closed
@hoodmane

Description

@hoodmane

I've been working on getting rust panics to work with wasm error handling. It is possible to compile the rust code and get valid generated code, but panics cannot be caught with catch_unwind. My best guess is that the problem is that the Rust compiler try intrinsic is wrong. The generated wasm has a throw instruction but no try or catch.

@aheejin

I am compiling rust code with the following environment variables:

export CARGO_BUILD_TARGET=wasm32-unknown-emscripten
export CARGO_TARGET_WASM32_UNKNOWN_EMSCRIPTEN_LINKER=emcc

export RUSTFLAGS= \
	-C link-arg=-sSIDE_MODULE=2 \
	-C link-arg=-sWASM_BIGINT \
	-C link-arg=-fwasm-exceptions \
	-C link-arg=-sDISABLE_EXCEPTION_CATCHING=1 \
	-C llvm-args=-enable-emscripten-cxx-exceptions=0 \
	-C llvm-args=-wasm-enable-sjlj \
	-Z link-native-libraries=no

my rust library looks like:

#[no_mangle]
pub extern "C" fn panic_test(n: i32) -> i32 {
    println!("panic test start {}", n);
    let result = panic::catch_unwind(|| {
        f(n)
    });
    println!("panic test end {}, {:?}", n, result);
    if let Ok(k) = result {
        return k - 1;
    } else {
        return -66;
    }
}

#[inline(never)]
fn f(n: i32) -> i32 {
    println!("f start {}", n);
    let result = g(n);
    println!("f end {}", n);
    return result - 1;
}

#[inline(never)]
fn g(n: i32) -> i32 {
    println!("g start {}", n);
    if n > 20 {
        panic!("oops!");
    }
    println!("g end {}", n);
    return n - 1;
}

The try intrinsic is here:
https://github.com/rust-lang/rust/blob/master/compiler/rustc_codegen_llvm/src/intrinsic.rs#L683-L707
it seems to be missing at least calls to __cxa_begin_catch and __cxa_end_catch, and the landingpad looks like it's specific to js exception handling.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions