use Void to ensure closure diverges

This commit is contained in:
John Ericson 2015-08-24 21:42:26 -07:00 committed by edef
parent c83143511e
commit 5411f10460
7 changed files with 22 additions and 6 deletions

View File

@ -7,6 +7,9 @@ build = "build.rs"
[build-dependencies]
gcc = "0.3.3"
[dependencies]
void = "0.0.5"
[features]
default = ["os", "valgrind"]
os = ["libc"]

View File

@ -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;

View File

@ -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 {

View File

@ -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);

View File

@ -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);

View File

@ -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 {

View File

@ -12,6 +12,8 @@
#[macro_use]
extern crate std;
extern crate void;
pub use context::Context;
pub use stack::Stack;