File: emcripten-catch-unwind.rs

package info (click to toggle)
rustc-web 1.85.0%2Bdfsg3-1~deb12u3
  • links: PTS, VCS
  • area: main
  • in suites: bookworm-proposed-updates
  • size: 1,759,988 kB
  • sloc: xml: 158,127; python: 35,830; javascript: 19,497; cpp: 19,002; sh: 17,245; ansic: 13,127; asm: 4,376; makefile: 1,056; lisp: 29; perl: 29; ruby: 19; sql: 11
file content (66 lines) | stat: -rw-r--r-- 1,747 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
//@ compile-flags: -O --target wasm32-unknown-emscripten
//@ needs-llvm-components: webassembly

// Emscripten has its own unique implementation of catch_unwind (in `codegen_emcc_try`),
// make sure it generates something reasonable.

#![feature(no_core, lang_items, intrinsics, rustc_attrs)]
#![crate_type = "lib"]
#![no_std]
#![no_core]

#[lang = "sized"]
trait Sized {}
#[lang = "freeze"]
trait Freeze {}
#[lang = "copy"]
trait Copy {}

impl<T> Copy for *mut T {}

#[rustc_intrinsic]
fn size_of<T>() -> usize {
    loop {}
}

extern "rust-intrinsic" {
    fn catch_unwind(
        try_fn: fn(_: *mut u8),
        data: *mut u8,
        catch_fn: fn(_: *mut u8, _: *mut u8),
    ) -> i32;
}

// CHECK-LABEL: @ptr_size
#[no_mangle]
pub fn ptr_size() -> usize {
    // CHECK: ret [[PTR_SIZE:.*]]
    size_of::<*mut u8>()
}

// CHECK-LABEL: @test_catch_unwind
#[no_mangle]
pub unsafe fn test_catch_unwind(
    try_fn: fn(_: *mut u8),
    data: *mut u8,
    catch_fn: fn(_: *mut u8, _: *mut u8),
) -> i32 {
    // CHECK: start:
    // CHECK: [[ALLOCA:%.*]] = alloca

    // CHECK: catch.i:
    // CHECK: [[LANDINGPAD:%.*]] = landingpad
    // CHECK: [[EXCEPTION:%.*]] = extractvalue {{.*}} [[LANDINGPAD]], 0
    // CHECK: [[SELECTOR:%.*]] = extractvalue {{.*}} [[LANDINGPAD]], 1

    // CHECK: [[IS_RUST_EXN:%.*]] = icmp eq {{.*}}[[SELECTOR]]
    // CHECK: [[IS_RUST_EXN_I8:%.*]] = zext i1 [[IS_RUST_EXN]] to i8

    // CHECK: store ptr [[EXCEPTION]], ptr [[ALLOCA]]
    // CHECK: [[IS_RUST_SLOT:%.*]] = getelementptr inbounds{{( nuw)?}} i8, ptr [[ALLOCA]], [[PTR_SIZE]]
    // CHECK: store i8 [[IS_RUST_EXN_I8]], ptr [[IS_RUST_SLOT]]

    // CHECK: call void %catch_fn(ptr %data, ptr nonnull [[ALLOCA]])

    catch_unwind(try_fn, data, catch_fn)
}