Skip to content

Instantly share code, notes, and snippets.

@gnzlbg
Last active January 20, 2019 20:00
Show Gist options
  • Save gnzlbg/450e40e40019f8b790eddfa382c110ef to your computer and use it in GitHub Desktop.
Save gnzlbg/450e40e40019f8b790eddfa382c110ef to your computer and use it in GitHub Desktop.

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