Expose fringe::STACK_ALIGNMENT, and make OwnedStack respect it.

master
whitequark 2016-09-02 22:14:07 +00:00 committed by edef
parent 0ca4bc86ff
commit c6ece101e2
7 changed files with 29 additions and 13 deletions

View File

@ -40,6 +40,8 @@
// when unwinding as well as returning normally, because LLVM does not do it for us.
use stack::Stack;
pub const STACK_ALIGNMENT: usize = 4;
#[derive(Debug, Clone)]
pub struct StackPointer(*mut usize);

View File

@ -41,6 +41,8 @@
// when unwinding as well as returning normally, because LLVM does not do it for us.
use stack::Stack;
pub const STACK_ALIGNMENT: usize = 16;
#[derive(Debug, Clone)]
pub struct StackPointer(*mut usize);

View File

@ -45,6 +45,8 @@
// when unwinding as well as returning normally, because LLVM does not do it for us.
use stack::Stack;
pub const STACK_ALIGNMENT: usize = 16;
#[derive(Debug, Clone)]
pub struct StackPointer(*mut usize);

View File

@ -5,7 +5,7 @@
// http://opensource.org/licenses/MIT>, at your option. This file may not be
// copied, modified, or distributed except according to those terms.
#![feature(asm, naked_functions, cfg_target_vendor)]
#![cfg_attr(feature = "alloc", feature(alloc))]
#![cfg_attr(feature = "alloc", feature(alloc, heap_api))]
#![cfg_attr(test, feature(test, thread_local, const_fn))]
#![no_std]
@ -45,6 +45,10 @@ pub use owned_stack::OwnedStack;
pub use os::Stack as OsStack;
mod arch;
/// Minimum alignment of a stack base address on the target platform.
pub const STACK_ALIGNMENT: usize = arch::STACK_ALIGNMENT;
mod debug;
mod context;

View File

@ -3,18 +3,22 @@
// See the LICENSE file included in this distribution.
extern crate alloc;
use self::alloc::raw_vec::RawVec;
use core::slice;
use self::alloc::heap;
use self::alloc::boxed::Box;
/// OwnedStack allocates on heap and owns a non-guarded stack.
/// OwnedStack holds a non-guarded, heap-allocated stack.
#[derive(Debug)]
pub struct OwnedStack(Box<[u8]>);
impl OwnedStack {
/// Allocates a new stack with exactly `size` accessible bytes using
/// the default Rust allocator.
/// Allocates a new stack with exactly `size` accessible bytes and alignment appropriate
/// for the current platform using the default Rust allocator.
pub fn new(size: usize) -> OwnedStack {
OwnedStack(unsafe { RawVec::with_capacity(size).into_box() })
unsafe {
let ptr = heap::allocate(size, ::STACK_ALIGNMENT);
OwnedStack(Box::from_raw(slice::from_raw_parts_mut(ptr, size)))
}
}
}

View File

@ -2,8 +2,10 @@
// Copyright (c) whitequark <whitequark@whitequark.org>
// See the LICENSE file included in this distribution.
/// SliceStack holds a non-guarded stack allocated elsewhere and provided as a mutable
/// slice.
/// SliceStack holds a non-guarded stack allocated elsewhere and provided as a mutable slice.
///
/// Any slice used in a SliceStack must adhere to the [Stack contract][contract].
/// [contract]: trait.Stack.html
#[derive(Debug)]
pub struct SliceStack<'a>(pub &'a mut [u8]);

View File

@ -11,17 +11,17 @@
/// To preserve memory safety, an implementation of this trait must fulfill
/// the following contract:
///
/// * The base of the stack must be aligned to a platform-specific boundary.
/// * The base address of the stack must be aligned to
/// a [`STACK_ALIGNMENT`][align]-byte boundary.
/// * Every address between the base and the limit must be readable and writable.
///
/// On any platform supported by libfringe, it is safe to align the stack to a 16-byte boundary.
/// The platform ABI document lists the specific alignment requirement.
/// [align]: constant.STACK_ALIGNMENT.html
pub trait Stack {
/// Returns the base of the stack.
/// Returns the base address of the stack.
/// On all modern architectures, the stack grows downwards,
/// so this is the highest address.
fn base(&self) -> *mut u8;
/// Returns the limit of the stack.
/// Returns the limit address of the stack.
/// On all modern architectures, the stack grows downwards,
/// so this is the lowest address.
fn limit(&self) -> *mut u8;