forked from M-Labs/libfringe
use Void to ensure closure diverges
This commit is contained in:
parent
c83143511e
commit
5411f10460
|
@ -7,6 +7,9 @@ build = "build.rs"
|
|||
[build-dependencies]
|
||||
gcc = "0.3.3"
|
||||
|
||||
[dependencies]
|
||||
void = "0.0.5"
|
||||
|
||||
[features]
|
||||
default = ["os", "valgrind"]
|
||||
os = ["libc"]
|
||||
|
|
|
@ -15,6 +15,7 @@ fn main() {
|
|||
let mut ctx = Context::new(stack, move || {
|
||||
println!("it's alive!");
|
||||
(*ctx_slot).swap();
|
||||
panic!("Do not come back!")
|
||||
});
|
||||
|
||||
ctx_slot = &mut ctx;
|
||||
|
|
|
@ -5,10 +5,13 @@ use core::mem::{size_of, align_of};
|
|||
use core::cmp::max;
|
||||
use core::ptr;
|
||||
|
||||
use void::{self, Void};
|
||||
|
||||
use super::imp::STACK_ALIGN;
|
||||
|
||||
pub unsafe extern "C" fn rust_trampoline<F: FnOnce()>(f: *const F) {
|
||||
ptr::read(f)()
|
||||
pub unsafe extern "C" fn rust_trampoline<F>(f: *const F) -> !
|
||||
where F: FnOnce() -> Void {
|
||||
void::unreachable(ptr::read(f)())
|
||||
}
|
||||
|
||||
pub unsafe fn push<T>(spp: &mut *mut usize, value: T) -> *mut T {
|
||||
|
|
|
@ -3,6 +3,8 @@
|
|||
// See the LICENSE file included in this distribution.
|
||||
use core::prelude::*;
|
||||
|
||||
use void::Void;
|
||||
|
||||
use stack::Stack;
|
||||
use super::common::{push, rust_trampoline};
|
||||
|
||||
|
@ -16,7 +18,8 @@ pub struct Registers {
|
|||
|
||||
impl Registers {
|
||||
#[inline]
|
||||
pub unsafe fn new<S, F>(stack: &mut S, f: F) -> Registers where S: Stack, F: FnOnce() {
|
||||
pub unsafe fn new<S, F>(stack: &mut S, f: F) -> Registers
|
||||
where S: Stack, F: FnOnce() -> Void {
|
||||
let sp_limit = stack.limit();
|
||||
let mut sp = stack.top() as *mut usize;
|
||||
let f_ptr = push(&mut sp, f);
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
// Copyright (c) 2015, edef <edef@edef.eu>
|
||||
// See the LICENSE file included in this distribution.
|
||||
use stack::Stack;
|
||||
use void::Void;
|
||||
use super::common::{push, rust_trampoline};
|
||||
|
||||
pub const STACK_ALIGN: usize = 16;
|
||||
|
@ -14,7 +15,8 @@ pub struct Registers {
|
|||
|
||||
impl Registers {
|
||||
#[inline]
|
||||
pub unsafe fn new<S, F>(stack: &mut S, f: F) -> Registers where S: Stack, F: FnOnce() {
|
||||
pub unsafe fn new<S, F>(stack: &mut S, f: F) -> Registers
|
||||
where S: Stack, F: FnOnce() -> Void {
|
||||
let sp_limit = stack.limit();
|
||||
let mut sp = stack.top() as *mut usize;
|
||||
let f_ptr = push(&mut sp, f);
|
||||
|
|
|
@ -2,6 +2,9 @@
|
|||
// Copyright (c) 2015, edef <edef@edef.eu>
|
||||
// See the LICENSE file included in this distribution.
|
||||
use core::marker::PhantomData;
|
||||
|
||||
use void::Void;
|
||||
|
||||
use arch::Registers;
|
||||
use stack;
|
||||
use debug::StackId;
|
||||
|
@ -27,10 +30,9 @@ unsafe impl<'a, Stack> Send for Context<'a, Stack>
|
|||
impl<'a, Stack> Context<'a, Stack> where Stack: stack::Stack {
|
||||
/// Create a new Context. When it is swapped into,
|
||||
/// it will call the passed closure.
|
||||
/// The closure shouldn't return - doing that will abort the process.
|
||||
#[inline]
|
||||
pub unsafe fn new<F>(mut stack: Stack, f: F) -> Context<'a, Stack>
|
||||
where F: FnOnce() + Send + 'a {
|
||||
where F: FnOnce() -> Void + Send + 'a {
|
||||
let stack_id = StackId::register(&mut stack);
|
||||
let regs = Registers::new(&mut stack, f);
|
||||
Context {
|
||||
|
|
|
@ -12,6 +12,8 @@
|
|||
#[macro_use]
|
||||
extern crate std;
|
||||
|
||||
extern crate void;
|
||||
|
||||
pub use context::Context;
|
||||
pub use stack::Stack;
|
||||
|
||||
|
|
Loading…
Reference in New Issue