FractalFir / FractalFir/rustc_codegen_clr

C unwinding with setjmp/longjmp

Open
#66 2 comments 3 reactions 0 assignees View on GitHub
Dominant language
Rust
Stars
2.1k
Forks
55
PR merge metrics
No merged PRs in 30d

Description

`setjmp`/`longjmp` based exception handling isn't particularly performant when cleanup frames are abundant, but it's supported by C89. Translation needs `thread_local` or some polyfill, though, which is C11.

Thread local state:

```c
#include
#include
extern thread_local jmp_buf thread_jmp_buf;
```

`unwind continue` is trivial; nothing changes:

```rust
_1 = f() -> [return: bb1, unwind continue];
```

```c
L1 = f();
goto bb1;
```

Cleanup adds to the jmp_buf stack:

```rust
_1 = f() -> [return: bb1, unwind: bb2];
```

```c
jmp_buf tmp_jmp_buf; // scratch space

tmp_jmp_buf = thread_jmp_buf;
if (setjmp(thread_jmp_buf)) {
thread_jmp_buf = tmp_jmp_buf;
goto bb2;
}
L1 = f();
thread_jmp_buf = tmp_jmp_buf;
goto bb1;
```

Resuming an unwind is then a call to `longjmp`:

```rust
resume;
```

```c
longjmp(thread_jmp_buf, 1);
```

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.