Skip to content

Instantly share code, notes, and snippets.

@gnzlbg gnzlbg/setlongjmp_draft.md
Last active Jan 20, 2019

Embed
What would you like to do?

Proposal:

Add setjmp and longjmp with the following semantics:

pub type JmpBuf = <implementation-defined>;

/// Saves the current execution context into `env`. If `longjmp(env, val)` is used 
/// to restore execution at this call site, this function returns `val`. Otherwise, 
/// it returns `0`. 
#[rustc_returns_twice]
pub unsafe fn setjmp(env: &mut JmpBuf) -> c_int;

/// Restores execution at the `setjmp` call-site that stored `env`, returning there the `value`.
///
/// If the function that called `setjmp` exits before the call to `longjmp`, the behavior is 
/// undefined.
///
/// All variables for which `drop` would be called if `longjmp` was to be replaced with 
/// `panic!` and `setjmp` with `catch_unwind` are not dropped.
pub unsafe fn longjmp(env: &JmpBuf, value: NonZero<c_int>);

The invocation of setjmp can appear only in the following contexts:

  • the entire controlling expression of match, e.g. match setjmp(b) { ... }.
  • if setenv(b) $int_rel_op $integer_constant_expression { ... }
  • the entire expression of an expression statement: setjmp(b);

If setjmp appears in any other context, the behavior is undefined.

Upon return to the scope of setjmp, all accessible objects, floating-point status flags, and other components of the abstract machine have the same values as they had when longjmp was executed, except for the local variables in setjmp's scope whose values have been changed since the setjmp invocation. The behavior of accessing these via non-volatile reads or writes is undefined.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.