Remove #[fixed_stack_segment] and #[rust_stack]

These two attributes are no longer useful now that Rust has decided to leave
segmented stacks behind. It is assumed that the rust task's stack is always
large enough to make an FFI call (due to the stack being very large).

There's always the case of stack overflow, however, to consider. This does not
change the behavior of stack overflow in Rust. This is still normally triggered
by the __morestack function and aborts the whole process.

C stack overflow will continue to corrupt the stack, however (as it did before
this commit as well). The future improvement of a guard page at the end of every
rust stack is still unimplemented and is intended to be the mechanism through
which we attempt to detect C stack overflow.

Closes #8822
Closes #10155
This commit is contained in:
Alex Crichton 2013-11-06 15:16:04 -08:00
parent 4059b5c4b3
commit 7755ffd013
111 changed files with 259 additions and 1045 deletions

View File

@ -19,10 +19,9 @@ extern {
fn snappy_max_compressed_length(source_length: size_t) -> size_t;
}
#[fixed_stack_segment]
fn main() {
let x = unsafe { snappy_max_compressed_length(100) };
println(fmt!("max compressed length of a 100 byte buffer: %?", x));
println!("max compressed length of a 100 byte buffer: {}", x);
}
~~~~
@ -36,11 +35,6 @@ interfaces that aren't thread-safe, and almost any function that takes a pointer
valid for all possible inputs since the pointer could be dangling, and raw pointers fall outside of
Rust's safe memory model.
Finally, the `#[fixed_stack_segment]` annotation that appears on
`main()` instructs the Rust compiler that when `main()` executes, it
should request a "very large" stack segment. More details on
stack management can be found in the following sections.
When declaring the argument types to a foreign function, the Rust compiler will not check if the
declaration is correct, so specifying it correctly is part of keeping the binding correct at
runtime.
@ -81,8 +75,6 @@ length is number of elements currently contained, and the capacity is the total
the allocated memory. The length is less than or equal to the capacity.
~~~~ {.xfail-test}
#[fixed_stack_segment]
#[inline(never)]
pub fn validate_compressed_buffer(src: &[u8]) -> bool {
unsafe {
snappy_validate_compressed_buffer(vec::raw::to_ptr(src), src.len() as size_t) == 0
@ -94,36 +86,6 @@ The `validate_compressed_buffer` wrapper above makes use of an `unsafe` block, b
guarantee that calling it is safe for all inputs by leaving off `unsafe` from the function
signature.
The `validate_compressed_buffer` wrapper is also annotated with two
attributes `#[fixed_stack_segment]` and `#[inline(never)]`. The
purpose of these attributes is to guarantee that there will be
sufficient stack for the C function to execute. This is necessary
because Rust, unlike C, does not assume that the stack is allocated in
one continuous chunk. Instead, we rely on a *segmented stack* scheme,
in which the stack grows and shrinks as necessary. C code, however,
expects one large stack, and so callers of C functions must request a
large stack segment to ensure that the C routine will not run off the
end of the stack.
The compiler includes a lint mode that will report an error if you
call a C function without a `#[fixed_stack_segment]` attribute. More
details on the lint mode are given in a later section.
You may be wondering why we include a `#[inline(never)]` directive.
This directive informs the compiler never to inline this function.
While not strictly necessary, it is usually a good idea to use an
`#[inline(never)]` directive in concert with `#[fixed_stack_segment]`.
The reason is that if a fn annotated with `fixed_stack_segment` is
inlined, then its caller also inherits the `fixed_stack_segment`
annotation. This means that rather than requesting a large stack
segment only for the duration of the call into C, the large stack
segment would be used for the entire duration of the caller. This is
not necessarily *bad* -- it can for example be more efficient,
particularly if `validate_compressed_buffer()` is called multiple
times in a row -- but it does work against the purpose of the
segmented stack scheme, which is to keep stacks small and thus
conserve address space.
The `snappy_compress` and `snappy_uncompress` functions are more complex, since a buffer has to be
allocated to hold the output too.
@ -134,8 +96,6 @@ the true length after compression for setting the length.
~~~~ {.xfail-test}
pub fn compress(src: &[u8]) -> ~[u8] {
#[fixed_stack_segment]; #[inline(never)];
unsafe {
let srclen = src.len() as size_t;
let psrc = vec::raw::to_ptr(src);
@ -156,8 +116,6 @@ format and `snappy_uncompressed_length` will retrieve the exact buffer size requ
~~~~ {.xfail-test}
pub fn uncompress(src: &[u8]) -> Option<~[u8]> {
#[fixed_stack_segment]; #[inline(never)];
unsafe {
let srclen = src.len() as size_t;
let psrc = vec::raw::to_ptr(src);
@ -181,98 +139,28 @@ pub fn uncompress(src: &[u8]) -> Option<~[u8]> {
For reference, the examples used here are also available as an [library on
GitHub](https://github.com/thestinger/rust-snappy).
# Automatic wrappers
# Stack management
Sometimes writing Rust wrappers can be quite tedious. For example, if
function does not take any pointer arguments, often there is no need
for translating types. In such cases, it is usually still a good idea
to have a Rust wrapper so as to manage the segmented stacks, but you
can take advantage of the (standard) `externfn!` macro to remove some
of the tedium.
Rust tasks by default run on a "large stack". This is actually implemented as a
reserving a large segment of the address space and then lazily mapping in pages
as they are needed. When calling an external C function, the code is invoked on
the same stack as the rust stack. This means that there is no extra
stack-switching mechanism in place because it is assumed that the large stack
for the rust task is plenty for the C function to have.
In the initial section, we showed an extern block that added a call
to a specific snappy API:
A planned future improvement (net yet implemented at the time of this writing)
is to have a guard page at the end of every rust stack. No rust function will
hit this guard page (due to rust's usage of LLVM's __morestack). The intention
for this unmapped page is to prevent infinite recursion in C from overflowing
onto other rust stacks. If the guard page is hit, then the process will be
terminated with a message saying that the guard page was hit.
~~~~ {.xfail-test}
use std::libc::size_t;
#[link_args = "-lsnappy"]
extern {
fn snappy_max_compressed_length(source_length: size_t) -> size_t;
}
#[fixed_stack_segment]
fn main() {
let x = unsafe { snappy_max_compressed_length(100) };
println(fmt!("max compressed length of a 100 byte buffer: %?", x));
}
~~~~
To avoid the need to create a wrapper fn for `snappy_max_compressed_length()`,
and also to avoid the need to think about `#[fixed_stack_segment]`, we
could simply use the `externfn!` macro instead, as shown here:
~~~~ {.xfail-test}
use std::libc::size_t;
externfn!(#[link_args = "-lsnappy"]
fn snappy_max_compressed_length(source_length: size_t) -> size_t)
fn main() {
let x = unsafe { snappy_max_compressed_length(100) };
println(fmt!("max compressed length of a 100 byte buffer: %?", x));
}
~~~~
As you can see from the example, `externfn!` replaces the extern block
entirely. After macro expansion, it will create something like this:
~~~~ {.xfail-test}
use std::libc::size_t;
// Automatically generated by
// externfn!(#[link_args = "-lsnappy"]
// fn snappy_max_compressed_length(source_length: size_t) -> size_t)
unsafe fn snappy_max_compressed_length(source_length: size_t) -> size_t {
#[fixed_stack_segment]; #[inline(never)];
return snappy_max_compressed_length(source_length);
#[link_args = "-lsnappy"]
extern {
fn snappy_max_compressed_length(source_length: size_t) -> size_t;
}
}
fn main() {
let x = unsafe { snappy_max_compressed_length(100) };
println(fmt!("max compressed length of a 100 byte buffer: %?", x));
}
~~~~
# Segmented stacks and the linter
By default, whenever you invoke a non-Rust fn, the `cstack` lint will
check that one of the following conditions holds:
1. The call occurs inside of a fn that has been annotated with
`#[fixed_stack_segment]`;
2. The call occurs inside of an `extern fn`;
3. The call occurs within a stack closure created by some other
safe fn.
All of these conditions ensure that you are running on a large stack
segment. However, they are sometimes too strict. If your application
will be making many calls into C, it is often beneficial to promote
the `#[fixed_stack_segment]` attribute higher up the call chain. For
example, the Rust compiler actually labels main itself as requiring a
`#[fixed_stack_segment]`. In such cases, the linter is just an
annoyance, because all C calls that occur from within the Rust
compiler are made on a large stack. Another situation where this
frequently occurs is on a 64-bit architecture, where large stacks are
the default. In cases, you can disable the linter by including a
`#[allow(cstack)]` directive somewhere, which permits violations of
the "cstack" rules given above (you can also use `#[warn(cstack)]` to
convert the errors into warnings, if you prefer).
For normal external function usage, this all means that there shouldn't be any
need for any extra effort on a user's perspective. The C stack naturally
interleaves with the rust stack, and it's "large enough" for both to
interoperate. If, however, it is determined that a larger stack is necessary,
there are appropriate functions in the task spawning API to control the size of
the stack of the task which is spawned.
# Destructors
@ -296,9 +184,6 @@ pub struct Unique<T> {
impl<T: Send> Unique<T> {
pub fn new(value: T) -> Unique<T> {
#[fixed_stack_segment];
#[inline(never)];
unsafe {
let ptr = malloc(std::mem::size_of::<T>() as size_t) as *mut T;
assert!(!ptr::is_null(ptr));
@ -322,9 +207,6 @@ impl<T: Send> Unique<T> {
#[unsafe_destructor]
impl<T: Send> Drop for Unique<T> {
fn drop(&mut self) {
#[fixed_stack_segment];
#[inline(never)];
unsafe {
let x = intrinsics::init(); // dummy value to swap in
// moving the object out is needed to call the destructor
@ -384,8 +266,8 @@ extern {
}
fn main() {
println(fmt!("You have readline version %d installed.",
rl_readline_version as int));
println!("You have readline version {} installed.",
rl_readline_version as int);
}
~~~

View File

@ -162,7 +162,6 @@ mod tests {
}
impl Runnable for LibcFree {
#[fixed_stack_segment]
fn run(~self) {
unsafe {
libc::free(self.mem)
@ -171,9 +170,6 @@ mod tests {
}
fn malloc(n: size_t) -> CVec<u8> {
#[fixed_stack_segment];
#[inline(never)];
unsafe {
let mem = libc::malloc(n);

View File

@ -47,8 +47,6 @@ static TINFL_FLAG_PARSE_ZLIB_HEADER : c_int = 0x1; // parse zlib header and adle
static TDEFL_WRITE_ZLIB_HEADER : c_int = 0x01000; // write zlib header and adler32 checksum
fn deflate_bytes_internal(bytes: &[u8], flags: c_int) -> ~[u8] {
#[fixed_stack_segment]; #[inline(never)];
do bytes.as_imm_buf |b, len| {
unsafe {
let mut outsz : size_t = 0;
@ -75,8 +73,6 @@ pub fn deflate_bytes_zlib(bytes: &[u8]) -> ~[u8] {
}
fn inflate_bytes_internal(bytes: &[u8], flags: c_int) -> ~[u8] {
#[fixed_stack_segment]; #[inline(never)];
do bytes.as_imm_buf |b, len| {
unsafe {
let mut outsz : size_t = 0;

View File

@ -38,6 +38,8 @@ Rust extras are part of the standard Rust distribution.
#[deny(non_camel_case_types)];
#[deny(missing_doc)];
#[allow(unrecognized_lint)]; // NOTE: remove after the next snapshot
#[allow(cstack)]; // NOTE: remove after the next snapshot.
use std::str::{StrSlice, OwnedStr};

View File

@ -220,8 +220,6 @@ fn optgroups() -> ~[getopts::groups::OptGroup] {
}
fn usage(binary: &str, helpstr: &str) {
#[fixed_stack_segment]; #[inline(never)];
let message = format!("Usage: {} [OPTIONS] [FILTER]", binary);
println(groups::usage(message, optgroups()));
println("");

View File

@ -63,8 +63,6 @@ impl Ord for Timespec {
* nanoseconds since 1970-01-01T00:00:00Z.
*/
pub fn get_time() -> Timespec {
#[fixed_stack_segment]; #[inline(never)];
unsafe {
let mut sec = 0i64;
let mut nsec = 0i32;
@ -79,8 +77,6 @@ pub fn get_time() -> Timespec {
* in nanoseconds since an unspecified epoch.
*/
pub fn precise_time_ns() -> u64 {
#[fixed_stack_segment]; #[inline(never)];
unsafe {
let mut ns = 0u64;
rustrt::precise_time_ns(&mut ns);
@ -98,8 +94,6 @@ pub fn precise_time_s() -> f64 {
}
pub fn tzset() {
#[fixed_stack_segment]; #[inline(never)];
unsafe {
rustrt::rust_tzset();
}
@ -143,8 +137,6 @@ pub fn empty_tm() -> Tm {
/// Returns the specified time in UTC
pub fn at_utc(clock: Timespec) -> Tm {
#[fixed_stack_segment]; #[inline(never)];
unsafe {
let Timespec { sec, nsec } = clock;
let mut tm = empty_tm();
@ -160,8 +152,6 @@ pub fn now_utc() -> Tm {
/// Returns the specified time in the local timezone
pub fn at(clock: Timespec) -> Tm {
#[fixed_stack_segment]; #[inline(never)];
unsafe {
let Timespec { sec, nsec } = clock;
let mut tm = empty_tm();
@ -179,8 +169,6 @@ pub fn now() -> Tm {
impl Tm {
/// Convert time to the seconds from January 1, 1970
pub fn to_timespec(&self) -> Timespec {
#[fixed_stack_segment]; #[inline(never)];
unsafe {
let sec = match self.tm_gmtoff {
0_i32 => rustrt::rust_timegm(self),
@ -969,7 +957,6 @@ mod tests {
use std::libc;
#[cfg(windows)]
#[fixed_stack_segment]
fn set_time_zone() {
// Windows crt doesn't see any environment variable set by
// `SetEnvironmentVariable`, which `os::setenv` internally uses.

View File

@ -278,9 +278,6 @@ pub fn phase_3_run_analysis_passes(sess: Session,
time(time_passes, "loop checking", (), |_|
middle::check_loop::check_crate(ty_cx, crate));
time(time_passes, "stack checking", (), |_|
middle::stack_check::stack_check_crate(ty_cx, crate));
let middle::moves::MoveMaps {moves_map, moved_variables_set,
capture_map} =
time(time_passes, "compute moves", (), |_|
@ -428,7 +425,6 @@ pub fn stop_after_phase_5(sess: Session) -> bool {
return false;
}
#[fixed_stack_segment]
pub fn compile_input(sess: Session, cfg: ast::CrateConfig, input: &input,
outdir: &Option<Path>, output: &Option<Path>) {
// We need nested scopes here, because the intermediate results can keep
@ -703,12 +699,7 @@ pub fn build_session_options(binary: @str,
}
if debugging_opts & session::debug_llvm != 0 {
set_llvm_debug();
fn set_llvm_debug() {
#[fixed_stack_segment]; #[inline(never)];
unsafe { llvm::LLVMSetDebug(1); }
}
unsafe { llvm::LLVMSetDebug(1); }
}
let output_type =

View File

@ -19,11 +19,8 @@
#[crate_type = "lib"];
#[feature(macro_rules, globs, struct_variant, managed_boxes)];
// Rustc tasks always run on a fixed_stack_segment, so code in this
// module can call C functions (in particular, LLVM functions) with
// impunity.
#[allow(cstack)];
#[allow(unrecognized_lint)]; // NOTE: remove after the next snapshot
#[allow(cstack)]; // NOTE: remove after the next snapshot.
extern mod extra;
extern mod syntax;
@ -81,7 +78,6 @@ pub mod middle {
pub mod reachable;
pub mod graph;
pub mod cfg;
pub mod stack_check;
}
pub mod front {

View File

@ -8,9 +8,6 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// LLVM wrappers are intended to be called from trans,
// which already runs in a #[fixed_stack_segment]
#[allow(cstack)];
#[allow(non_uppercase_pattern_statics)];
use std::c_str::ToCStr;

View File

@ -63,7 +63,6 @@ use syntax::visit::Visitor;
#[deriving(Clone, Eq)]
pub enum lint {
ctypes,
cstack,
unused_imports,
unnecessary_qualification,
while_true,
@ -136,13 +135,6 @@ static lint_table: &'static [(&'static str, LintSpec)] = &[
default: warn
}),
("cstack",
LintSpec {
lint: cstack,
desc: "only invoke foreign functions from fixedstacksegment fns",
default: deny
}),
("unused_imports",
LintSpec {
lint: unused_imports,

View File

@ -1,182 +0,0 @@
// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
/*!
Lint mode to detect cases where we call non-Rust fns, which do not
have a stack growth check, from locations not annotated to request
large stacks.
*/
use middle::lint;
use middle::ty;
use syntax::ast;
use syntax::ast_map;
use syntax::attr;
use syntax::codemap::Span;
use syntax::visit;
use syntax::visit::Visitor;
use util::ppaux::Repr;
#[deriving(Clone)]
struct Context {
safe_stack: bool
}
struct StackCheckVisitor {
tcx: ty::ctxt,
}
impl Visitor<Context> for StackCheckVisitor {
fn visit_item(&mut self, i:@ast::item, e:Context) {
stack_check_item(self, i, e);
}
fn visit_fn(&mut self, fk:&visit::fn_kind, fd:&ast::fn_decl,
b:&ast::Block, s:Span, n:ast::NodeId, e:Context) {
stack_check_fn(self, fk, fd, b, s, n, e);
}
fn visit_expr(&mut self, ex:@ast::Expr, e:Context) {
stack_check_expr(self, ex, e);
}
}
pub fn stack_check_crate(tcx: ty::ctxt,
crate: &ast::Crate) {
let new_cx = Context { safe_stack: false };
let mut visitor = StackCheckVisitor { tcx: tcx };
visit::walk_crate(&mut visitor, crate, new_cx);
}
fn stack_check_item(v: &mut StackCheckVisitor,
item: @ast::item,
in_cx: Context) {
match item.node {
ast::item_fn(_, ast::extern_fn, _, _, _) => {
// an extern fn is already being called from C code...
let new_cx = Context {safe_stack: true};
visit::walk_item(v, item, new_cx);
}
ast::item_fn(*) => {
let safe_stack = fixed_stack_segment(item.attrs);
let new_cx = Context {safe_stack: safe_stack};
visit::walk_item(v, item, new_cx);
}
ast::item_impl(_, _, _, ref methods) => {
// visit_method() would make this nicer
for &method in methods.iter() {
let safe_stack = fixed_stack_segment(method.attrs);
let new_cx = Context {safe_stack: safe_stack};
visit::walk_method_helper(v, method, new_cx);
}
}
ast::item_trait(_, _, ref methods) => {
for method in methods.iter() {
match *method {
ast::provided(@ref method) => {
let safe_stack = fixed_stack_segment(method.attrs);
let new_cx = Context {safe_stack: safe_stack};
visit::walk_method_helper(v, method, new_cx);
}
ast::required(*) => ()
}
}
}
_ => {
visit::walk_item(v, item, in_cx);
}
}
fn fixed_stack_segment(attrs: &[ast::Attribute]) -> bool {
attr::contains_name(attrs, "fixed_stack_segment")
}
}
fn stack_check_fn<'a>(v: &mut StackCheckVisitor,
fk: &visit::fn_kind,
decl: &ast::fn_decl,
body: &ast::Block,
sp: Span,
id: ast::NodeId,
in_cx: Context) {
let safe_stack = match *fk {
visit::fk_method(*) | visit::fk_item_fn(*) => {
in_cx.safe_stack // see stack_check_item above
}
visit::fk_anon(*) | visit::fk_fn_block => {
match ty::get(ty::node_id_to_type(v.tcx, id)).sty {
ty::ty_bare_fn(*) |
ty::ty_closure(ty::ClosureTy {sigil: ast::OwnedSigil, _}) => {
false
}
_ => {
in_cx.safe_stack
}
}
}
};
let new_cx = Context {safe_stack: safe_stack};
debug!("stack_check_fn(safe_stack={}, id={:?})", safe_stack, id);
visit::walk_fn(v, fk, decl, body, sp, id, new_cx);
}
fn stack_check_expr<'a>(v: &mut StackCheckVisitor,
expr: @ast::Expr,
cx: Context) {
debug!("stack_check_expr(safe_stack={}, expr={})",
cx.safe_stack, expr.repr(v.tcx));
if !cx.safe_stack {
match expr.node {
ast::ExprCall(callee, _, _) => {
let callee_ty = ty::expr_ty(v.tcx, callee);
debug!("callee_ty={}", callee_ty.repr(v.tcx));
match ty::get(callee_ty).sty {
ty::ty_bare_fn(ref fty) => {
if !fty.abis.is_rust() && !fty.abis.is_intrinsic() {
call_to_extern_fn(v, callee);
}
}
_ => {}
}
}
_ => {}
}
}
visit::walk_expr(v, expr, cx);
}
fn call_to_extern_fn(v: &mut StackCheckVisitor, callee: @ast::Expr) {
// Permit direct calls to extern fns that are annotated with
// #[rust_stack]. This is naturally a horrible pain to achieve.
match callee.node {
ast::ExprPath(*) => {
match v.tcx.def_map.find(&callee.id) {
Some(&ast::DefFn(id, _)) if id.crate == ast::LOCAL_CRATE => {
match v.tcx.items.find(&id.node) {
Some(&ast_map::node_foreign_item(item, _, _, _)) => {
if attr::contains_name(item.attrs, "rust_stack") {
return;
}
}
_ => {}
}
}
_ => {}
}
}
_ => {}
}
v.tcx.sess.add_lint(lint::cstack,
callee.id,
callee.span,
format!("invoking non-Rust fn in fn without \
\\#[fixed_stack_segment]"));
}

View File

@ -495,12 +495,6 @@ pub fn set_always_inline(f: ValueRef) {
lib::llvm::SetFunctionAttribute(f, lib::llvm::AlwaysInlineAttribute)
}
pub fn set_fixed_stack_segment(f: ValueRef) {
do "fixed-stack-segment".with_c_str |buf| {
unsafe { llvm::LLVMAddFunctionAttrString(f, buf); }
}
}
pub fn set_no_split_stack(f: ValueRef) {
do "no-split-stack".with_c_str |buf| {
unsafe { llvm::LLVMAddFunctionAttrString(f, buf); }
@ -1889,7 +1883,7 @@ pub fn trans_closure(ccx: @mut CrateContext,
self_arg: self_arg,
param_substs: Option<@param_substs>,
id: ast::NodeId,
attributes: &[ast::Attribute],
_attributes: &[ast::Attribute],
output_type: ty::t,
maybe_load_env: &fn(@mut FunctionContext)) {
ccx.stats.n_closures += 1;
@ -1919,12 +1913,6 @@ pub fn trans_closure(ccx: @mut CrateContext,
let arg_tys = ty::ty_fn_args(node_id_type(bcx, id));
let raw_llargs = create_llargs_for_fn_args(fcx, self_arg, decl.inputs);
// Set the fixed stack segment flag if necessary.
if attr::contains_name(attributes, "fixed_stack_segment") {
set_no_inline(fcx.llfn);
set_fixed_stack_segment(fcx.llfn);
}
bcx = copy_args_to_allocas(fcx, bcx, decl.inputs, raw_llargs, arg_tys);
maybe_load_env(fcx);

View File

@ -25,7 +25,6 @@ use middle::trans::glue;
use middle::ty;
use syntax::ast;
use syntax::ast_map;
use syntax::attr;
use util::ppaux::ty_to_str;
use middle::trans::machine::llsize_of;
use middle::trans::type_::Type;
@ -35,7 +34,7 @@ pub fn trans_intrinsic(ccx: @mut CrateContext,
item: &ast::foreign_item,
path: ast_map::path,
substs: @param_substs,
attributes: &[ast::Attribute],
_attributes: &[ast::Attribute],
ref_id: Option<ast::NodeId>) {
debug!("trans_intrinsic(item.ident={})", ccx.sess.str_of(item.ident));
@ -149,11 +148,6 @@ pub fn trans_intrinsic(ccx: @mut CrateContext,
set_always_inline(fcx.llfn);
// Set the fixed stack segment flag if necessary.
if attr::contains_name(attributes, "fixed_stack_segment") {
set_fixed_stack_segment(fcx.llfn);
}
let mut bcx = fcx.entry_bcx.unwrap();
let first_real_arg = fcx.arg_pos(0u);

View File

@ -8,8 +8,6 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#[allow(cstack)]; // each rendering task runs on a fixed stack segment.
//! Markdown formatting for rustdoc
//!
//! This module implements markdown formatting through the sundown C-library

View File

@ -717,7 +717,6 @@ impl Context {
port: &SharedPort<Work>,
chan: &SharedChan<Work>,
prog_chan: &SharedChan<Progress>) {
#[fixed_stack_segment]; // we hit markdown FFI *a lot*
local_data::set(cache_key, cache);
loop {

View File

@ -462,7 +462,6 @@ pub fn versionize(p: &Path, v: &Version) -> Path {
#[cfg(target_os = "win32")]
pub fn chmod_read_only(p: &Path) -> bool {
#[fixed_stack_segment];
unsafe {
do p.with_c_str |src_buf| {
libc::chmod(src_buf, S_IRUSR as libc::c_int) == 0 as libc::c_int
@ -472,7 +471,6 @@ pub fn chmod_read_only(p: &Path) -> bool {
#[cfg(not(target_os = "win32"))]
pub fn chmod_read_only(p: &Path) -> bool {
#[fixed_stack_segment];
unsafe {
do p.with_c_str |src_buf| {
libc::chmod(src_buf, S_IRUSR as libc::mode_t) == 0

View File

@ -2319,7 +2319,7 @@ fn test_c_dependency_ok() {
let dir = dir.path();
writeFile(&dir.join_many(["src", "cdep-0.1", "main.rs"]),
"#[link_args = \"-lfoo\"]\nextern { fn f(); } \
\n#[fixed_stack_segment]\nfn main() { unsafe { f(); } }");
\nfn main() { unsafe { f(); } }");
writeFile(&dir.join_many(["src", "cdep-0.1", "foo.c"]), "void f() {}");
debug!("dir = {}", dir.display());
@ -2340,7 +2340,7 @@ fn test_c_dependency_no_rebuilding() {
let dir = dir.path();
writeFile(&dir.join_many(["src", "cdep-0.1", "main.rs"]),
"#[link_args = \"-lfoo\"]\nextern { fn f(); } \
\n#[fixed_stack_segment]\nfn main() { unsafe { f(); } }");
\nfn main() { unsafe { f(); } }");
writeFile(&dir.join_many(["src", "cdep-0.1", "foo.c"]), "void f() {}");
debug!("dir = {}", dir.display());
@ -2371,7 +2371,7 @@ fn test_c_dependency_yes_rebuilding() {
let dir = dir.path();
writeFile(&dir.join_many(["src", "cdep-0.1", "main.rs"]),
"#[link_args = \"-lfoo\"]\nextern { fn f(); } \
\n#[fixed_stack_segment]\nfn main() { unsafe { f(); } }");
\nfn main() { unsafe { f(); } }");
let c_file_name = dir.join_many(["src", "cdep-0.1", "foo.c"]);
writeFile(&c_file_name, "void f() {}");

View File

@ -361,7 +361,6 @@ impl FileWatcher {
}
fn seek_common(&mut self, pos: i64, whence: c_int) ->
Result<u64, IoError>{
#[fixed_stack_segment]; #[inline(never)];
unsafe {
match libc::lseek(self.fd, pos as libc::off_t, whence) {
-1 => {

View File

@ -44,6 +44,8 @@ via `close` and `delete` methods.
#[crate_type = "lib"];
#[feature(macro_rules, globs)];
#[allow(unrecognized_lint)]; // NOTE: remove after the next snapshot
#[allow(cstack)]; // NOTE: remove after the next snapshot.
use std::cast::transmute;
use std::cast;

View File

@ -35,7 +35,6 @@ use uvll::sockaddr;
/// Generic functions related to dealing with sockaddr things
////////////////////////////////////////////////////////////////////////////////
#[fixed_stack_segment]
fn socket_addr_as_sockaddr<T>(addr: SocketAddr, f: &fn(*sockaddr) -> T) -> T {
let malloc = match addr.ip {
Ipv4Addr(*) => uvll::rust_malloc_ip4_addr,
@ -51,7 +50,6 @@ fn socket_addr_as_sockaddr<T>(addr: SocketAddr, f: &fn(*sockaddr) -> T) -> T {
}
}
#[fixed_stack_segment]
pub fn sockaddr_to_socket_addr(addr: *sockaddr) -> SocketAddr {
unsafe {
let ip_size = if uvll::rust_is_ipv4_sockaddr(addr) == 1 {
@ -112,7 +110,6 @@ enum SocketNameKind {
Udp
}
#[fixed_stack_segment]
fn socket_name(sk: SocketNameKind, handle: *c_void) -> Result<SocketAddr, IoError> {
unsafe {
let getsockname = match sk {

View File

@ -364,8 +364,6 @@ pub enum uv_membership {
}
pub unsafe fn malloc_handle(handle: uv_handle_type) -> *c_void {
#[fixed_stack_segment]; #[inline(never)];
assert!(handle != UV_UNKNOWN_HANDLE && handle != UV_HANDLE_TYPE_MAX);
let size = uv_handle_size(handle);
let p = malloc(size);
@ -374,14 +372,10 @@ pub unsafe fn malloc_handle(handle: uv_handle_type) -> *c_void {
}
pub unsafe fn free_handle(v: *c_void) {
#[fixed_stack_segment]; #[inline(never)];
free(v)
}
pub unsafe fn malloc_req(req: uv_req_type) -> *c_void {
#[fixed_stack_segment]; #[inline(never)];
assert!(req != UV_UNKNOWN_REQ && req != UV_REQ_TYPE_MAX);
let size = uv_req_size(req);
let p = malloc(size);
@ -390,14 +384,11 @@ pub unsafe fn malloc_req(req: uv_req_type) -> *c_void {
}
pub unsafe fn free_req(v: *c_void) {
#[fixed_stack_segment]; #[inline(never)];
free(v)
}
#[test]
fn handle_sanity_check() {
#[fixed_stack_segment]; #[inline(never)];
unsafe {
assert_eq!(UV_HANDLE_TYPE_MAX as uint, rust_uv_handle_type_max());
}
@ -405,7 +396,6 @@ fn handle_sanity_check() {
#[test]
fn request_sanity_check() {
#[fixed_stack_segment]; #[inline(never)];
unsafe {
assert_eq!(UV_REQ_TYPE_MAX as uint, rust_uv_req_type_max());
}
@ -413,132 +403,113 @@ fn request_sanity_check() {
// XXX Event loops ignore SIGPIPE by default.
pub unsafe fn loop_new() -> *c_void {
#[fixed_stack_segment]; #[inline(never)];
return rust_uv_loop_new();
}
pub unsafe fn get_udp_handle_from_send_req(send_req: *uv_udp_send_t) -> *uv_udp_t {
#[fixed_stack_segment]; #[inline(never)];
return rust_uv_get_udp_handle_from_send_req(send_req);
}
pub unsafe fn uv_write(req: *uv_write_t,
stream: *uv_stream_t,
buf_in: &[uv_buf_t],
cb: uv_write_cb) -> c_int {
externfn!(fn uv_write(req: *uv_write_t, stream: *uv_stream_t,
buf_in: *uv_buf_t, buf_cnt: c_int,
cb: uv_write_cb) -> c_int)
extern {
fn uv_write(req: *uv_write_t, stream: *uv_stream_t,
buf_in: *uv_buf_t, buf_cnt: c_int,
cb: uv_write_cb) -> c_int;
}
let buf_ptr = vec::raw::to_ptr(buf_in);
let buf_cnt = buf_in.len() as i32;
return uv_write(req, stream, buf_ptr, buf_cnt, cb);
}
pub unsafe fn uv_udp_send(req: *uv_udp_send_t,
handle: *uv_udp_t,
buf_in: &[uv_buf_t],
addr: *sockaddr,
cb: uv_udp_send_cb) -> c_int {
extern {
fn uv_udp_send(req: *uv_write_t, stream: *uv_stream_t,
buf_in: *uv_buf_t, buf_cnt: c_int, addr: *sockaddr,
cb: uv_udp_send_cb) -> c_int;
}
let buf_ptr = vec::raw::to_ptr(buf_in);
let buf_cnt = buf_in.len() as i32;
return uv_udp_send(req, handle, buf_ptr, buf_cnt, addr, cb);
}
pub unsafe fn get_udp_handle_from_send_req(send_req: *uv_udp_send_t) -> *uv_udp_t {
return rust_uv_get_udp_handle_from_send_req(send_req);
}
pub unsafe fn process_pid(p: *uv_process_t) -> c_int {
#[fixed_stack_segment]; #[inline(never)];
return rust_uv_process_pid(p);
}
pub unsafe fn set_stdio_container_flags(c: *uv_stdio_container_t,
flags: libc::c_int) {
#[fixed_stack_segment]; #[inline(never)];
rust_set_stdio_container_flags(c, flags);
}
pub unsafe fn set_stdio_container_fd(c: *uv_stdio_container_t,
fd: libc::c_int) {
#[fixed_stack_segment]; #[inline(never)];
rust_set_stdio_container_fd(c, fd);
}
pub unsafe fn set_stdio_container_stream(c: *uv_stdio_container_t,
stream: *uv_stream_t) {
#[fixed_stack_segment]; #[inline(never)];
rust_set_stdio_container_stream(c, stream);
}
// data access helpers
pub unsafe fn get_result_from_fs_req(req: *uv_fs_t) -> c_int {
#[fixed_stack_segment]; #[inline(never)];
rust_uv_get_result_from_fs_req(req)
}
pub unsafe fn get_ptr_from_fs_req(req: *uv_fs_t) -> *libc::c_void {
#[fixed_stack_segment]; #[inline(never)];
rust_uv_get_ptr_from_fs_req(req)
}
pub unsafe fn get_path_from_fs_req(req: *uv_fs_t) -> *c_char {
#[fixed_stack_segment]; #[inline(never)];
rust_uv_get_path_from_fs_req(req)
}
pub unsafe fn get_loop_from_fs_req(req: *uv_fs_t) -> *uv_loop_t {
#[fixed_stack_segment]; #[inline(never)];
rust_uv_get_loop_from_fs_req(req)
}
pub unsafe fn get_loop_from_getaddrinfo_req(req: *uv_getaddrinfo_t) -> *uv_loop_t {
#[fixed_stack_segment]; #[inline(never)];
rust_uv_get_loop_from_getaddrinfo_req(req)
}
pub unsafe fn get_loop_for_uv_handle<T>(handle: *T) -> *c_void {
#[fixed_stack_segment]; #[inline(never)];
return rust_uv_get_loop_for_uv_handle(handle as *c_void);
}
pub unsafe fn get_stream_handle_from_connect_req(connect: *uv_connect_t) -> *uv_stream_t {
#[fixed_stack_segment]; #[inline(never)];
return rust_uv_get_stream_handle_from_connect_req(connect);
}
pub unsafe fn get_stream_handle_from_write_req(write_req: *uv_write_t) -> *uv_stream_t {
#[fixed_stack_segment]; #[inline(never)];
return rust_uv_get_stream_handle_from_write_req(write_req);
}
pub unsafe fn get_data_for_uv_loop(loop_ptr: *c_void) -> *c_void {
#[fixed_stack_segment]; #[inline(never)];
rust_uv_get_data_for_uv_loop(loop_ptr)
}
pub unsafe fn set_data_for_uv_loop(loop_ptr: *c_void, data: *c_void) {
#[fixed_stack_segment]; #[inline(never)];
rust_uv_set_data_for_uv_loop(loop_ptr, data);
}
pub unsafe fn get_data_for_uv_handle<T>(handle: *T) -> *c_void {
#[fixed_stack_segment]; #[inline(never)];
return rust_uv_get_data_for_uv_handle(handle as *c_void);
}
pub unsafe fn set_data_for_uv_handle<T, U>(handle: *T, data: *U) {
#[fixed_stack_segment]; #[inline(never)];
rust_uv_set_data_for_uv_handle(handle as *c_void, data as *c_void);
}
pub unsafe fn get_data_for_req<T>(req: *T) -> *c_void {
#[fixed_stack_segment]; #[inline(never)];
return rust_uv_get_data_for_req(req as *c_void);
}
pub unsafe fn set_data_for_req<T, U>(req: *T, data: *U) {
#[fixed_stack_segment]; #[inline(never)];
rust_uv_set_data_for_req(req as *c_void, data as *c_void);
}
pub unsafe fn populate_stat(req_in: *uv_fs_t, stat_out: *uv_stat_t) {
#[fixed_stack_segment]; #[inline(never)];
rust_uv_populate_uv_stat(req_in, stat_out)
}
pub unsafe fn guess_handle(handle: c_int) -> c_int {
#[fixed_stack_segment]; #[inline(never)];
rust_uv_guess_handle(handle)
}
@ -594,172 +565,158 @@ extern {
stream: *uv_stream_t);
fn rust_uv_process_pid(p: *uv_process_t) -> c_int;
fn rust_uv_guess_handle(fd: c_int) -> c_int;
// generic uv functions
pub fn uv_loop_delete(l: *uv_loop_t);
pub fn uv_handle_size(ty: uv_handle_type) -> size_t;
pub fn uv_req_size(ty: uv_req_type) -> size_t;
pub fn uv_run(l: *uv_loop_t, mode: uv_run_mode) -> c_int;
pub fn uv_close(h: *uv_handle_t, cb: uv_close_cb);
pub fn uv_walk(l: *uv_loop_t, cb: uv_walk_cb, arg: *c_void);
pub fn uv_buf_init(base: *c_char, len: c_uint) -> uv_buf_t;
pub fn uv_strerror(err: c_int) -> *c_char;
pub fn uv_err_name(err: c_int) -> *c_char;
pub fn uv_listen(s: *uv_stream_t, backlog: c_int,
cb: uv_connection_cb) -> c_int;
pub fn uv_accept(server: *uv_stream_t, client: *uv_stream_t) -> c_int;
pub fn uv_read_start(stream: *uv_stream_t,
on_alloc: uv_alloc_cb,
on_read: uv_read_cb) -> c_int;
pub fn uv_read_stop(stream: *uv_stream_t) -> c_int;
// idle bindings
pub fn uv_idle_init(l: *uv_loop_t, i: *uv_idle_t) -> c_int;
pub fn uv_idle_start(i: *uv_idle_t, cb: uv_idle_cb) -> c_int;
pub fn uv_idle_stop(i: *uv_idle_t) -> c_int;
// async bindings
pub fn uv_async_init(l: *uv_loop_t, a: *uv_async_t,
cb: uv_async_cb) -> c_int;
pub fn uv_async_send(a: *uv_async_t);
// tcp bindings
pub fn uv_tcp_init(l: *uv_loop_t, h: *uv_tcp_t) -> c_int;
pub fn uv_tcp_connect(c: *uv_connect_t, h: *uv_tcp_t,
addr: *sockaddr, cb: uv_connect_cb) -> c_int;
pub fn uv_tcp_bind(t: *uv_tcp_t, addr: *sockaddr) -> c_int;
pub fn uv_ip4_name(src: *sockaddr, dst: *c_char,
size: size_t) -> c_int;
pub fn uv_ip6_name(src: *sockaddr, dst: *c_char,
size: size_t) -> c_int;
pub fn uv_tcp_nodelay(h: *uv_tcp_t, enable: c_int) -> c_int;
pub fn uv_tcp_keepalive(h: *uv_tcp_t, enable: c_int,
delay: c_uint) -> c_int;
pub fn uv_tcp_simultaneous_accepts(h: *uv_tcp_t, enable: c_int) -> c_int;
pub fn uv_tcp_getsockname(h: *uv_tcp_t, name: *sockaddr,
len: *mut c_int) -> c_int;
pub fn uv_tcp_getpeername(h: *uv_tcp_t, name: *sockaddr,
len: *mut c_int) -> c_int;
pub fn uv_ip4_addr(ip: *c_char, port: c_int, addr: *sockaddr) -> c_int;
pub fn uv_ip6_addr(ip: *c_char, port: c_int, addr: *sockaddr) -> c_int;
// udp bindings
pub fn uv_udp_init(l: *uv_loop_t, h: *uv_udp_t) -> c_int;
pub fn uv_udp_bind(h: *uv_udp_t, addr: *sockaddr, flags: c_uint) -> c_int;
pub fn uv_udp_recv_start(server: *uv_udp_t,
on_alloc: uv_alloc_cb,
on_recv: uv_udp_recv_cb) -> c_int;
pub fn uv_udp_set_membership(handle: *uv_udp_t, multicast_addr: *c_char,
interface_addr: *c_char,
membership: uv_membership) -> c_int;
pub fn uv_udp_recv_stop(server: *uv_udp_t) -> c_int;
pub fn uv_udp_set_multicast_loop(handle: *uv_udp_t, on: c_int) -> c_int;
pub fn uv_udp_set_multicast_ttl(handle: *uv_udp_t, ttl: c_int) -> c_int;
pub fn uv_udp_set_ttl(handle: *uv_udp_t, ttl: c_int) -> c_int;
pub fn uv_udp_set_broadcast(handle: *uv_udp_t, on: c_int) -> c_int;
pub fn uv_udp_getsockname(h: *uv_udp_t, name: *sockaddr,
len: *mut c_int) -> c_int;
// timer bindings
pub fn uv_timer_init(l: *uv_loop_t, t: *uv_timer_t) -> c_int;
pub fn uv_timer_start(t: *uv_timer_t, cb: uv_timer_cb,
timeout: libc::uint64_t,
repeat: libc::uint64_t) -> c_int;
pub fn uv_timer_stop(handle: *uv_timer_t) -> c_int;
// fs operations
pub fn uv_fs_open(loop_ptr: *uv_loop_t, req: *uv_fs_t, path: *c_char,
flags: c_int, mode: c_int, cb: uv_fs_cb) -> c_int;
pub fn uv_fs_unlink(loop_ptr: *uv_loop_t, req: *uv_fs_t, path: *c_char,
cb: uv_fs_cb) -> c_int;
pub fn uv_fs_write(l: *uv_loop_t, req: *uv_fs_t, fd: c_int, buf: *c_void,
len: size_t, offset: i64, cb: uv_fs_cb) -> c_int;
pub fn uv_fs_read(l: *uv_loop_t, req: *uv_fs_t, fd: c_int, buf: *c_void,
len: size_t, offset: i64, cb: uv_fs_cb) -> c_int;
pub fn uv_fs_close(l: *uv_loop_t, req: *uv_fs_t, fd: c_int,
cb: uv_fs_cb) -> c_int;
pub fn uv_fs_stat(l: *uv_loop_t, req: *uv_fs_t, path: *c_char,
cb: uv_fs_cb) -> c_int;
pub fn uv_fs_fstat(l: *uv_loop_t, req: *uv_fs_t, fd: c_int,
cb: uv_fs_cb) -> c_int;
pub fn uv_fs_mkdir(l: *uv_loop_t, req: *uv_fs_t, path: *c_char,
mode: c_int, cb: uv_fs_cb) -> c_int;
pub fn uv_fs_rmdir(l: *uv_loop_t, req: *uv_fs_t, path: *c_char,
cb: uv_fs_cb) -> c_int;
pub fn uv_fs_readdir(l: *uv_loop_t, req: *uv_fs_t, path: *c_char,
flags: c_int, cb: uv_fs_cb) -> c_int;
pub fn uv_fs_req_cleanup(req: *uv_fs_t);
pub fn uv_fs_fsync(handle: *uv_loop_t, req: *uv_fs_t, file: c_int,
cb: uv_fs_cb) -> c_int;
pub fn uv_fs_fdatasync(handle: *uv_loop_t, req: *uv_fs_t, file: c_int,
cb: uv_fs_cb) -> c_int;
pub fn uv_fs_ftruncate(handle: *uv_loop_t, req: *uv_fs_t, file: c_int,
offset: i64, cb: uv_fs_cb) -> c_int;
pub fn uv_fs_readlink(handle: *uv_loop_t, req: *uv_fs_t, file: *c_char,
cb: uv_fs_cb) -> c_int;
pub fn uv_fs_symlink(handle: *uv_loop_t, req: *uv_fs_t, src: *c_char,
dst: *c_char, flags: c_int, cb: uv_fs_cb) -> c_int;
pub fn uv_fs_rename(handle: *uv_loop_t, req: *uv_fs_t, src: *c_char,
dst: *c_char, cb: uv_fs_cb) -> c_int;
pub fn uv_fs_utime(handle: *uv_loop_t, req: *uv_fs_t, path: *c_char,
atime: c_double, mtime: c_double,
cb: uv_fs_cb) -> c_int;
pub fn uv_fs_link(handle: *uv_loop_t, req: *uv_fs_t, src: *c_char,
dst: *c_char, cb: uv_fs_cb) -> c_int;
pub fn uv_fs_chown(handle: *uv_loop_t, req: *uv_fs_t, src: *c_char,
uid: uv_uid_t, gid: uv_gid_t, cb: uv_fs_cb) -> c_int;
pub fn uv_fs_chmod(handle: *uv_loop_t, req: *uv_fs_t, path: *c_char,
mode: c_int, cb: uv_fs_cb) -> c_int;
pub fn uv_fs_lstat(handle: *uv_loop_t, req: *uv_fs_t, file: *c_char,
cb: uv_fs_cb) -> c_int;
// getaddrinfo
pub fn uv_getaddrinfo(loop_: *uv_loop_t, req: *uv_getaddrinfo_t,
getaddrinfo_cb: uv_getaddrinfo_cb,
node: *c_char, service: *c_char,
hints: *addrinfo) -> c_int;
pub fn uv_freeaddrinfo(ai: *addrinfo);
// process spawning
pub fn uv_spawn(loop_ptr: *uv_loop_t, outptr: *uv_process_t,
options: *uv_process_options_t) -> c_int;
pub fn uv_process_kill(p: *uv_process_t, signum: c_int) -> c_int;
// pipes
pub fn uv_pipe_init(l: *uv_loop_t, p: *uv_pipe_t, ipc: c_int) -> c_int;
pub fn uv_pipe_open(pipe: *uv_pipe_t, file: c_int) -> c_int;
pub fn uv_pipe_bind(pipe: *uv_pipe_t, name: *c_char) -> c_int;
pub fn uv_pipe_connect(req: *uv_connect_t, handle: *uv_pipe_t,
name: *c_char, cb: uv_connect_cb);
// tty
pub fn uv_tty_init(l: *uv_loop_t, tty: *uv_tty_t, fd: c_int,
readable: c_int) -> c_int;
pub fn uv_tty_set_mode(tty: *uv_tty_t, mode: c_int) -> c_int;
pub fn uv_tty_get_winsize(tty: *uv_tty_t, width: *c_int,
height: *c_int) -> c_int;
// signals
pub fn uv_signal_init(loop_: *uv_loop_t, handle: *uv_signal_t) -> c_int;
pub fn uv_signal_start(h: *uv_signal_t, cb: uv_signal_cb,
signum: c_int) -> c_int;
pub fn uv_signal_stop(handle: *uv_signal_t) -> c_int;
}
// generic uv functions
externfn!(fn uv_loop_delete(l: *uv_loop_t))
externfn!(fn uv_handle_size(ty: uv_handle_type) -> size_t)
externfn!(fn uv_req_size(ty: uv_req_type) -> size_t)
externfn!(fn uv_run(l: *uv_loop_t, mode: uv_run_mode) -> c_int)
externfn!(fn uv_close(h: *uv_handle_t, cb: uv_close_cb))
externfn!(fn uv_walk(l: *uv_loop_t, cb: uv_walk_cb, arg: *c_void))
externfn!(fn uv_buf_init(base: *c_char, len: c_uint) -> uv_buf_t)
externfn!(fn uv_strerror(err: c_int) -> *c_char)
externfn!(fn uv_err_name(err: c_int) -> *c_char)
externfn!(fn uv_listen(s: *uv_stream_t, backlog: c_int,
cb: uv_connection_cb) -> c_int)
externfn!(fn uv_accept(server: *uv_stream_t, client: *uv_stream_t) -> c_int)
externfn!(fn uv_read_start(stream: *uv_stream_t,
on_alloc: uv_alloc_cb,
on_read: uv_read_cb) -> c_int)
externfn!(fn uv_read_stop(stream: *uv_stream_t) -> c_int)
// idle bindings
externfn!(fn uv_idle_init(l: *uv_loop_t, i: *uv_idle_t) -> c_int)
externfn!(fn uv_idle_start(i: *uv_idle_t, cb: uv_idle_cb) -> c_int)
externfn!(fn uv_idle_stop(i: *uv_idle_t) -> c_int)
// async bindings
externfn!(fn uv_async_init(l: *uv_loop_t, a: *uv_async_t,
cb: uv_async_cb) -> c_int)
externfn!(fn uv_async_send(a: *uv_async_t))
// tcp bindings
externfn!(fn uv_tcp_init(l: *uv_loop_t, h: *uv_tcp_t) -> c_int)
externfn!(fn uv_tcp_connect(c: *uv_connect_t, h: *uv_tcp_t,
addr: *sockaddr, cb: uv_connect_cb) -> c_int)
externfn!(fn uv_tcp_bind(t: *uv_tcp_t, addr: *sockaddr) -> c_int)
externfn!(fn uv_ip4_name(src: *sockaddr, dst: *c_char,
size: size_t) -> c_int)
externfn!(fn uv_ip6_name(src: *sockaddr, dst: *c_char,
size: size_t) -> c_int)
externfn!(fn uv_tcp_nodelay(h: *uv_tcp_t, enable: c_int) -> c_int)
externfn!(fn uv_tcp_keepalive(h: *uv_tcp_t, enable: c_int,
delay: c_uint) -> c_int)
externfn!(fn uv_tcp_simultaneous_accepts(h: *uv_tcp_t, enable: c_int) -> c_int)
externfn!(fn uv_tcp_getsockname(h: *uv_tcp_t, name: *sockaddr,
len: *mut c_int) -> c_int)
externfn!(fn uv_tcp_getpeername(h: *uv_tcp_t, name: *sockaddr,
len: *mut c_int) -> c_int)
externfn!(fn uv_ip4_addr(ip: *c_char, port: c_int, addr: *sockaddr) -> c_int)
externfn!(fn uv_ip6_addr(ip: *c_char, port: c_int, addr: *sockaddr) -> c_int)
// udp bindings
externfn!(fn uv_udp_init(l: *uv_loop_t, h: *uv_udp_t) -> c_int)
externfn!(fn uv_udp_bind(h: *uv_udp_t, addr: *sockaddr, flags: c_uint) -> c_int)
externfn!(fn uv_udp_recv_start(server: *uv_udp_t,
on_alloc: uv_alloc_cb,
on_recv: uv_udp_recv_cb) -> c_int)
externfn!(fn uv_udp_set_membership(handle: *uv_udp_t, multicast_addr: *c_char,
interface_addr: *c_char,
membership: uv_membership) -> c_int)
externfn!(fn uv_udp_recv_stop(server: *uv_udp_t) -> c_int)
externfn!(fn uv_udp_set_multicast_loop(handle: *uv_udp_t, on: c_int) -> c_int)
externfn!(fn uv_udp_set_multicast_ttl(handle: *uv_udp_t, ttl: c_int) -> c_int)
externfn!(fn uv_udp_set_ttl(handle: *uv_udp_t, ttl: c_int) -> c_int)
externfn!(fn uv_udp_set_broadcast(handle: *uv_udp_t, on: c_int) -> c_int)
externfn!(fn uv_udp_getsockname(h: *uv_udp_t, name: *sockaddr,
len: *mut c_int) -> c_int)
pub unsafe fn uv_udp_send(req: *uv_udp_send_t,
handle: *uv_udp_t,
buf_in: &[uv_buf_t],
addr: *sockaddr,
cb: uv_udp_send_cb) -> c_int {
externfn!(fn uv_udp_send(req: *uv_write_t, stream: *uv_stream_t,
buf_in: *uv_buf_t, buf_cnt: c_int, addr: *sockaddr,
cb: uv_udp_send_cb) -> c_int)
let buf_ptr = vec::raw::to_ptr(buf_in);
let buf_cnt = buf_in.len() as i32;
return uv_udp_send(req, handle, buf_ptr, buf_cnt, addr, cb);
}
// timer bindings
externfn!(fn uv_timer_init(l: *uv_loop_t, t: *uv_timer_t) -> c_int)
externfn!(fn uv_timer_start(t: *uv_timer_t, cb: uv_timer_cb,
timeout: libc::uint64_t,
repeat: libc::uint64_t) -> c_int)
externfn!(fn uv_timer_stop(handle: *uv_timer_t) -> c_int)
// fs operations
externfn!(fn uv_fs_open(loop_ptr: *uv_loop_t, req: *uv_fs_t, path: *c_char,
flags: c_int, mode: c_int, cb: uv_fs_cb) -> c_int)
externfn!(fn uv_fs_unlink(loop_ptr: *uv_loop_t, req: *uv_fs_t, path: *c_char,
cb: uv_fs_cb) -> c_int)
externfn!(fn uv_fs_write(l: *uv_loop_t, req: *uv_fs_t, fd: c_int, buf: *c_void,
len: size_t, offset: i64, cb: uv_fs_cb) -> c_int)
externfn!(fn uv_fs_read(l: *uv_loop_t, req: *uv_fs_t, fd: c_int, buf: *c_void,
len: size_t, offset: i64, cb: uv_fs_cb) -> c_int)
externfn!(fn uv_fs_close(l: *uv_loop_t, req: *uv_fs_t, fd: c_int,
cb: uv_fs_cb) -> c_int)
externfn!(fn uv_fs_stat(l: *uv_loop_t, req: *uv_fs_t, path: *c_char,
cb: uv_fs_cb) -> c_int)
externfn!(fn uv_fs_fstat(l: *uv_loop_t, req: *uv_fs_t, fd: c_int,
cb: uv_fs_cb) -> c_int)
externfn!(fn uv_fs_mkdir(l: *uv_loop_t, req: *uv_fs_t, path: *c_char,
mode: c_int, cb: uv_fs_cb) -> c_int)
externfn!(fn uv_fs_rmdir(l: *uv_loop_t, req: *uv_fs_t, path: *c_char,
cb: uv_fs_cb) -> c_int)
externfn!(fn uv_fs_readdir(l: *uv_loop_t, req: *uv_fs_t, path: *c_char,
flags: c_int, cb: uv_fs_cb) -> c_int)
externfn!(fn uv_fs_req_cleanup(req: *uv_fs_t))
externfn!(fn uv_fs_fsync(handle: *uv_loop_t, req: *uv_fs_t, file: c_int,
cb: uv_fs_cb) -> c_int)
externfn!(fn uv_fs_fdatasync(handle: *uv_loop_t, req: *uv_fs_t, file: c_int,
cb: uv_fs_cb) -> c_int)
externfn!(fn uv_fs_ftruncate(handle: *uv_loop_t, req: *uv_fs_t, file: c_int,
offset: i64, cb: uv_fs_cb) -> c_int)
externfn!(fn uv_fs_readlink(handle: *uv_loop_t, req: *uv_fs_t, file: *c_char,
cb: uv_fs_cb) -> c_int)
externfn!(fn uv_fs_symlink(handle: *uv_loop_t, req: *uv_fs_t, src: *c_char,
dst: *c_char, flags: c_int, cb: uv_fs_cb) -> c_int)
externfn!(fn uv_fs_rename(handle: *uv_loop_t, req: *uv_fs_t, src: *c_char,
dst: *c_char, cb: uv_fs_cb) -> c_int)
externfn!(fn uv_fs_utime(handle: *uv_loop_t, req: *uv_fs_t, path: *c_char,
atime: c_double, mtime: c_double,
cb: uv_fs_cb) -> c_int)
externfn!(fn uv_fs_link(handle: *uv_loop_t, req: *uv_fs_t, src: *c_char,
dst: *c_char, cb: uv_fs_cb) -> c_int)
externfn!(fn uv_fs_chown(handle: *uv_loop_t, req: *uv_fs_t, src: *c_char,
uid: uv_uid_t, gid: uv_gid_t, cb: uv_fs_cb) -> c_int)
externfn!(fn uv_fs_chmod(handle: *uv_loop_t, req: *uv_fs_t, path: *c_char,
mode: c_int, cb: uv_fs_cb) -> c_int)
externfn!(fn uv_fs_lstat(handle: *uv_loop_t, req: *uv_fs_t, file: *c_char,
cb: uv_fs_cb) -> c_int)
// getaddrinfo
externfn!(fn uv_getaddrinfo(loop_: *uv_loop_t, req: *uv_getaddrinfo_t,
getaddrinfo_cb: uv_getaddrinfo_cb,
node: *c_char, service: *c_char,
hints: *addrinfo) -> c_int)
externfn!(fn uv_freeaddrinfo(ai: *addrinfo))
// process spawning
externfn!(fn uv_spawn(loop_ptr: *uv_loop_t, outptr: *uv_process_t,
options: *uv_process_options_t) -> c_int)
externfn!(fn uv_process_kill(p: *uv_process_t, signum: c_int) -> c_int)
// pipes
externfn!(fn uv_pipe_init(l: *uv_loop_t, p: *uv_pipe_t, ipc: c_int) -> c_int)
externfn!(fn uv_pipe_open(pipe: *uv_pipe_t, file: c_int) -> c_int)
externfn!(fn uv_pipe_bind(pipe: *uv_pipe_t, name: *c_char) -> c_int)
externfn!(fn uv_pipe_connect(req: *uv_connect_t, handle: *uv_pipe_t,
name: *c_char, cb: uv_connect_cb))
// tty
externfn!(fn uv_tty_init(l: *uv_loop_t, tty: *uv_tty_t, fd: c_int,
readable: c_int) -> c_int)
externfn!(fn uv_tty_set_mode(tty: *uv_tty_t, mode: c_int) -> c_int)
externfn!(fn uv_tty_get_winsize(tty: *uv_tty_t, width: *c_int,
height: *c_int) -> c_int)
// signals
externfn!(fn uv_signal_init(loop_: *uv_loop_t, handle: *uv_signal_t) -> c_int)
externfn!(fn uv_signal_start(h: *uv_signal_t, cb: uv_signal_cb,
signum: c_int) -> c_int)
externfn!(fn uv_signal_stop(handle: *uv_signal_t) -> c_int)
// libuv requires various system libraries to successfully link on some
// platforms
#[cfg(target_os = "linux")]

View File

@ -40,7 +40,9 @@ An example of creating and using a C string would be:
```rust
use std::libc;
externfn!(fn puts(s: *libc::c_char))
extern {
fn puts(s: *libc::c_char);
}
let my_string = "Hello, world!";
@ -179,7 +181,6 @@ impl CString {
impl Drop for CString {
fn drop(&mut self) {
#[fixed_stack_segment]; #[inline(never)];
if self.owns_buffer_ {
unsafe {
libc::free(self.buf as *libc::c_void)
@ -260,7 +261,6 @@ static BUF_LEN: uint = 128;
impl<'self> ToCStr for &'self [u8] {
fn to_c_str(&self) -> CString {
#[fixed_stack_segment]; #[inline(never)];
let mut cs = unsafe { self.to_c_str_unchecked() };
do cs.with_mut_ref |buf| {
check_for_null(*self, buf);
@ -269,7 +269,6 @@ impl<'self> ToCStr for &'self [u8] {
}
unsafe fn to_c_str_unchecked(&self) -> CString {
#[fixed_stack_segment]; #[inline(never)];
do self.as_imm_buf |self_buf, self_len| {
let buf = libc::malloc(self_len as libc::size_t + 1) as *mut u8;
if buf.is_null() {
@ -460,16 +459,12 @@ mod tests {
#[test]
fn test_unwrap() {
#[fixed_stack_segment]; #[inline(never)];
let c_str = "hello".to_c_str();
unsafe { libc::free(c_str.unwrap() as *libc::c_void) }
}
#[test]
fn test_with_ref() {
#[fixed_stack_segment]; #[inline(never)];
let c_str = "hello".to_c_str();
let len = unsafe { c_str.with_ref(|buf| libc::strlen(buf)) };
assert!(!c_str.is_null());

View File

@ -64,6 +64,8 @@
#[deny(non_camel_case_types)];
#[deny(missing_doc)];
#[allow(unrecognized_lint)]; // NOTE: remove after the next snapshot
#[allow(cstack)]; // NOTE: remove after the next snapshot.
// When testing libstd, bring in libuv as the I/O backend so tests can print
// things and all of the std::rt::io tests have an I/O interface to run on top

View File

@ -2857,11 +2857,7 @@ pub mod funcs {
// These are fine to execute on the Rust stack. They must be,
// in fact, because LLVM generates calls to them!
#[rust_stack]
#[inline]
pub fn memcmp(cx: *c_void, ct: *c_void, n: size_t) -> c_int;
#[rust_stack]
#[inline]
pub fn memchr(cx: *c_void, c: c_int, n: size_t) -> *c_void;
}
}
@ -3059,11 +3055,9 @@ pub mod funcs {
// doesn't link it correctly on i686, so we're going
// through a C function that mysteriously does work.
pub unsafe fn opendir(dirname: *c_char) -> *DIR {
#[fixed_stack_segment]; #[inline(never)];
rust_opendir(dirname)
}
pub unsafe fn readdir(dirp: *DIR) -> *dirent_t {
#[fixed_stack_segment]; #[inline(never)];
rust_readdir(dirp)
}

View File

@ -277,7 +277,6 @@ fn get_with<T: 'static, U>(key: Key<T>,
}
fn abort() -> ! {
#[fixed_stack_segment]; #[inline(never)];
unsafe { libc::abort() }
}

View File

@ -41,7 +41,7 @@ macro_rules! delegate(
use unstable::intrinsics;
$(
#[inline] #[fixed_stack_segment] #[inline(never)]
#[inline]
pub fn $name($( $arg : $arg_ty ),*) -> $rv {
unsafe {
$bound_name($( $arg ),*)

View File

@ -43,7 +43,7 @@ macro_rules! delegate(
use unstable::intrinsics;
$(
#[inline] #[fixed_stack_segment] #[inline(never)]
#[inline]
pub fn $name($( $arg : $arg_ty ),*) -> $rv {
unsafe {
$bound_name($( $arg ),*)

View File

@ -47,7 +47,6 @@ pub use os::consts::*;
/// Delegates to the libc close() function, returning the same return value.
pub fn close(fd: c_int) -> c_int {
#[fixed_stack_segment]; #[inline(never)];
unsafe {
libc::close(fd)
}
@ -58,7 +57,6 @@ static BUF_BYTES : uint = 2048u;
#[cfg(unix)]
pub fn getcwd() -> Path {
#[fixed_stack_segment]; #[inline(never)];
let mut buf = [0 as libc::c_char, ..BUF_BYTES];
do buf.as_mut_buf |buf, len| {
unsafe {
@ -73,7 +71,6 @@ pub fn getcwd() -> Path {
#[cfg(windows)]
pub fn getcwd() -> Path {
#[fixed_stack_segment]; #[inline(never)];
use libc::DWORD;
use libc::GetCurrentDirectoryW;
let mut buf = [0 as u16, ..BUF_BYTES];
@ -99,7 +96,6 @@ pub mod win32 {
pub fn fill_utf16_buf_and_decode(f: &fn(*mut u16, DWORD) -> DWORD)
-> Option<~str> {
#[fixed_stack_segment]; #[inline(never)];
unsafe {
let mut n = TMPBUF_SZ as DWORD;
@ -153,8 +149,10 @@ fn with_env_lock<T>(f: &fn() -> T) -> T {
};
}
externfn!(fn rust_take_env_lock());
externfn!(fn rust_drop_env_lock());
extern {
fn rust_take_env_lock();
fn rust_drop_env_lock();
}
}
/// Returns a vector of (variable, value) pairs for all the environment
@ -163,7 +161,6 @@ pub fn env() -> ~[(~str,~str)] {
unsafe {
#[cfg(windows)]
unsafe fn get_env_pairs() -> ~[~str] {
#[fixed_stack_segment]; #[inline(never)];
use c_str;
use str::StrSlice;
@ -185,8 +182,6 @@ pub fn env() -> ~[(~str,~str)] {
}
#[cfg(unix)]
unsafe fn get_env_pairs() -> ~[~str] {
#[fixed_stack_segment]; #[inline(never)];
extern {
fn rust_env_pairs() -> **libc::c_char;
}
@ -225,7 +220,6 @@ pub fn env() -> ~[(~str,~str)] {
/// Fetches the environment variable `n` from the current process, returning
/// None if the variable isn't set.
pub fn getenv(n: &str) -> Option<~str> {
#[fixed_stack_segment]; #[inline(never)];
unsafe {
do with_env_lock {
let s = do n.with_c_str |buf| {
@ -244,8 +238,6 @@ pub fn getenv(n: &str) -> Option<~str> {
/// Fetches the environment variable `n` from the current process, returning
/// None if the variable isn't set.
pub fn getenv(n: &str) -> Option<~str> {
#[fixed_stack_segment]; #[inline(never)];
unsafe {
do with_env_lock {
use os::win32::{as_utf16_p, fill_utf16_buf_and_decode};
@ -263,7 +255,6 @@ pub fn getenv(n: &str) -> Option<~str> {
/// Sets the environment variable `n` to the value `v` for the currently running
/// process
pub fn setenv(n: &str, v: &str) {
#[fixed_stack_segment]; #[inline(never)];
unsafe {
do with_env_lock {
do n.with_c_str |nbuf| {
@ -280,8 +271,6 @@ pub fn setenv(n: &str, v: &str) {
/// Sets the environment variable `n` to the value `v` for the currently running
/// process
pub fn setenv(n: &str, v: &str) {
#[fixed_stack_segment]; #[inline(never)];
unsafe {
do with_env_lock {
use os::win32::as_utf16_p;
@ -298,7 +287,6 @@ pub fn setenv(n: &str, v: &str) {
pub fn unsetenv(n: &str) {
#[cfg(unix)]
fn _unsetenv(n: &str) {
#[fixed_stack_segment]; #[inline(never)];
unsafe {
do with_env_lock {
do n.with_c_str |nbuf| {
@ -309,7 +297,6 @@ pub fn unsetenv(n: &str) {
}
#[cfg(windows)]
fn _unsetenv(n: &str) {
#[fixed_stack_segment]; #[inline(never)];
unsafe {
do with_env_lock {
use os::win32::as_utf16_p;
@ -330,7 +317,6 @@ pub struct Pipe {
#[cfg(unix)]
pub fn pipe() -> Pipe {
#[fixed_stack_segment]; #[inline(never)];
unsafe {
let mut fds = Pipe {input: 0 as c_int,
out: 0 as c_int };
@ -341,7 +327,6 @@ pub fn pipe() -> Pipe {
#[cfg(windows)]
pub fn pipe() -> Pipe {
#[fixed_stack_segment]; #[inline(never)];
unsafe {
// Windows pipes work subtly differently than unix pipes, and their
// inheritance has to be handled in a different way that I do not
@ -360,7 +345,6 @@ pub fn pipe() -> Pipe {
}
fn dup2(src: c_int, dst: c_int) -> c_int {
#[fixed_stack_segment]; #[inline(never)];
unsafe {
libc::dup2(src, dst)
}
@ -377,7 +361,6 @@ pub fn self_exe_path() -> Option<Path> {
#[cfg(target_os = "freebsd")]
fn load_self() -> Option<~[u8]> {
#[fixed_stack_segment]; #[inline(never)];
unsafe {
use libc::funcs::bsd44::*;
use libc::consts::os::extra::*;
@ -415,7 +398,6 @@ pub fn self_exe_path() -> Option<Path> {
#[cfg(target_os = "macos")]
fn load_self() -> Option<~[u8]> {
#[fixed_stack_segment]; #[inline(never)];
unsafe {
use libc::funcs::extra::_NSGetExecutablePath;
use vec;
@ -434,7 +416,6 @@ pub fn self_exe_path() -> Option<Path> {
#[cfg(windows)]
fn load_self() -> Option<~[u8]> {
#[fixed_stack_segment]; #[inline(never)];
unsafe {
use os::win32::fill_utf16_buf_and_decode;
do fill_utf16_buf_and_decode() |buf, sz| {
@ -555,7 +536,6 @@ pub fn change_dir(p: &Path) -> bool {
#[cfg(windows)]
fn chdir(p: &Path) -> bool {
#[fixed_stack_segment]; #[inline(never)];
unsafe {
use os::win32::as_utf16_p;
return do as_utf16_p(p.as_str().unwrap()) |buf| {
@ -566,7 +546,6 @@ pub fn change_dir(p: &Path) -> bool {
#[cfg(unix)]
fn chdir(p: &Path) -> bool {
#[fixed_stack_segment]; #[inline(never)];
do p.with_c_str |buf| {
unsafe {
libc::chdir(buf) == (0 as c_int)
@ -581,7 +560,6 @@ pub fn errno() -> int {
#[cfg(target_os = "macos")]
#[cfg(target_os = "freebsd")]
fn errno_location() -> *c_int {
#[fixed_stack_segment]; #[inline(never)];
#[nolink]
extern {
fn __error() -> *c_int;
@ -594,7 +572,6 @@ pub fn errno() -> int {
#[cfg(target_os = "linux")]
#[cfg(target_os = "android")]
fn errno_location() -> *c_int {
#[fixed_stack_segment]; #[inline(never)];
#[nolink]
extern {
fn __errno_location() -> *c_int;
@ -612,7 +589,6 @@ pub fn errno() -> int {
#[cfg(windows)]
/// Returns the platform-specific value of errno
pub fn errno() -> uint {
#[fixed_stack_segment]; #[inline(never)];
use libc::types::os::arch::extra::DWORD;
#[link_name = "kernel32"]
@ -634,8 +610,6 @@ pub fn last_os_error() -> ~str {
#[cfg(target_os = "freebsd")]
fn strerror_r(errnum: c_int, buf: *mut c_char, buflen: size_t)
-> c_int {
#[fixed_stack_segment]; #[inline(never)];
#[nolink]
extern {
fn strerror_r(errnum: c_int, buf: *mut c_char, buflen: size_t)
@ -651,7 +625,6 @@ pub fn last_os_error() -> ~str {
// So we just use __xpg_strerror_r which is always POSIX compliant
#[cfg(target_os = "linux")]
fn strerror_r(errnum: c_int, buf: *mut c_char, buflen: size_t) -> c_int {
#[fixed_stack_segment]; #[inline(never)];
#[nolink]
extern {
fn __xpg_strerror_r(errnum: c_int,
@ -679,8 +652,6 @@ pub fn last_os_error() -> ~str {
#[cfg(windows)]
fn strerror() -> ~str {
#[fixed_stack_segment]; #[inline(never)];
use libc::types::os::arch::extra::DWORD;
use libc::types::os::arch::extra::LPWSTR;
use libc::types::os::arch::extra::LPVOID;
@ -758,8 +729,6 @@ unsafe fn load_argc_and_argv(argc: c_int, argv: **c_char) -> ~[~str] {
*/
#[cfg(target_os = "macos")]
fn real_args() -> ~[~str] {
#[fixed_stack_segment]; #[inline(never)];
unsafe {
let (argc, argv) = (*_NSGetArgc() as c_int,
*_NSGetArgv() as **c_char);
@ -781,7 +750,6 @@ fn real_args() -> ~[~str] {
#[cfg(windows)]
fn real_args() -> ~[~str] {
#[fixed_stack_segment]; #[inline(never)];
use vec;
let mut nArgs: c_int = 0;
@ -858,8 +826,6 @@ fn round_up(from: uint, to: uint) -> uint {
#[cfg(unix)]
pub fn page_size() -> uint {
#[fixed_stack_segment]; #[inline(never)];
unsafe {
libc::sysconf(libc::_SC_PAGESIZE) as uint
}
@ -867,8 +833,6 @@ pub fn page_size() -> uint {
#[cfg(windows)]
pub fn page_size() -> uint {
#[fixed_stack_segment]; #[inline(never)];
unsafe {
let mut info = libc::SYSTEM_INFO::new();
libc::GetSystemInfo(&mut info);
@ -979,8 +943,6 @@ impl to_str::ToStr for MapError {
impl MemoryMap {
/// Create a new mapping with the given `options`, at least `min_len` bytes long.
pub fn new(min_len: uint, options: &[MapOption]) -> Result<MemoryMap, MapError> {
#[fixed_stack_segment]; #[inline(never)];
use libc::off_t;
let mut addr: *c_void = ptr::null();
@ -1043,8 +1005,6 @@ impl MemoryMap {
impl Drop for MemoryMap {
/// Unmap the mapping. Fails the task if `munmap` fails.
fn drop(&mut self) {
#[fixed_stack_segment]; #[inline(never)];
unsafe {
match libc::munmap(self.data as *c_void, self.len) {
0 => (),
@ -1062,8 +1022,6 @@ impl Drop for MemoryMap {
impl MemoryMap {
/// Create a new mapping with the given `options`, at least `min_len` bytes long.
pub fn new(min_len: uint, options: &[MapOption]) -> Result<MemoryMap, MapError> {
#[fixed_stack_segment]; #[inline(never)];
use libc::types::os::arch::extra::{LPVOID, DWORD, SIZE_T, HANDLE};
let mut lpAddress: LPVOID = ptr::mut_null();
@ -1156,8 +1114,6 @@ impl MemoryMap {
/// Granularity of MapAddr() and MapOffset() parameter values.
/// This may be greater than the value returned by page_size().
pub fn granularity() -> uint {
#[fixed_stack_segment]; #[inline(never)];
unsafe {
let mut info = libc::SYSTEM_INFO::new();
libc::GetSystemInfo(&mut info);
@ -1172,8 +1128,6 @@ impl Drop for MemoryMap {
/// Unmap the mapping. Fails the task if any of `VirtualFree`, `UnmapViewOfFile`, or
/// `CloseHandle` fail.
fn drop(&mut self) {
#[fixed_stack_segment]; #[inline(never)];
use libc::types::os::arch::extra::{LPCVOID, HANDLE};
use libc::consts::os::extra::FALSE;
@ -1490,8 +1444,6 @@ mod tests {
#[test]
fn memory_map_file() {
#[fixed_stack_segment]; #[inline(never)];
use result::{Ok, Err};
use os::*;
use libc::*;
@ -1499,16 +1451,12 @@ mod tests {
use rt::io::fs;
#[cfg(unix)]
#[fixed_stack_segment]
#[inline(never)]
fn lseek_(fd: c_int, size: uint) {
unsafe {
assert!(lseek(fd, size as off_t, SEEK_SET) == size as off_t);
}
}
#[cfg(windows)]
#[fixed_stack_segment]
#[inline(never)]
fn lseek_(fd: c_int, size: uint) {
unsafe {
assert!(lseek(fd, size as c_long, SEEK_SET) == size as c_long);

View File

@ -71,7 +71,7 @@ impl OSRng {
/// Create a new `OSRng`.
#[cfg(windows)]
pub fn new() -> OSRng {
externfn!(fn rust_win32_rand_acquire(phProv: *mut HCRYPTPROV))
extern { fn rust_win32_rand_acquire(phProv: *mut HCRYPTPROV); }
let mut hcp = 0;
unsafe {rust_win32_rand_acquire(&mut hcp)};
@ -106,7 +106,10 @@ impl Rng for OSRng {
unsafe { cast::transmute(v) }
}
fn fill_bytes(&mut self, v: &mut [u8]) {
externfn!(fn rust_win32_rand_gen(hProv: HCRYPTPROV, dwLen: DWORD, pbBuffer: *mut BYTE))
extern {
fn rust_win32_rand_gen(hProv: HCRYPTPROV, dwLen: DWORD,
pbBuffer: *mut BYTE);
}
do v.as_mut_buf |ptr, len| {
unsafe {rust_win32_rand_gen(self.hcryptprov, len as DWORD, ptr)}
@ -123,7 +126,7 @@ impl Drop for OSRng {
#[cfg(windows)]
fn drop(&mut self) {
externfn!(fn rust_win32_rand_release(hProv: HCRYPTPROV))
extern { fn rust_win32_rand_release(hProv: HCRYPTPROV); }
unsafe {rust_win32_rand_release(self.hcryptprov)}
}

View File

@ -117,9 +117,11 @@ mod imp {
}
}
externfn!(fn rust_take_global_args_lock())
externfn!(fn rust_drop_global_args_lock())
externfn!(fn rust_get_global_args_ptr() -> *mut Option<~~[~str]>)
extern {
fn rust_take_global_args_lock();
fn rust_drop_global_args_lock();
fn rust_get_global_args_ptr() -> *mut Option<~~[~str]>;
}
#[cfg(test)]
mod tests {

View File

@ -236,7 +236,6 @@ impl Drop for BasicPausible {
}
fn time() -> Time {
#[fixed_stack_segment]; #[inline(never)];
extern {
fn get_time(sec: &mut i64, nsec: &mut i32);
}

View File

@ -119,7 +119,6 @@ impl Context {
}
extern {
#[rust_stack]
fn swap_registers(out_regs: *mut Registers, in_regs: *Registers);
}
@ -376,7 +375,6 @@ pub unsafe fn record_sp_limit(limit: uint) {
unsafe fn target_record_sp_limit(limit: uint) {
return record_sp_limit(limit as *c_void);
extern {
#[rust_stack]
fn record_sp_limit(limit: *c_void);
}
}
@ -450,7 +448,6 @@ pub unsafe fn get_sp_limit() -> uint {
unsafe fn target_get_sp_limit() -> uint {
return get_sp_limit() as uint;
extern {
#[rust_stack]
fn get_sp_limit() -> *c_void;
}
}

View File

@ -49,8 +49,6 @@ pub fn get_crate_map() -> Option<&'static CrateMap<'static>> {
}
#[cfg(windows)]
#[fixed_stack_segment]
#[inline(never)]
pub fn get_crate_map() -> Option<&'static CrateMap<'static>> {
use cast::transmute;
use c_str::ToCStr;

View File

@ -14,7 +14,6 @@ use unstable::raw;
use mem::size_of;
extern {
#[rust_stack]
fn abort();
}
@ -36,8 +35,6 @@ fn align_to(size: uint, align: uint) -> uint {
/// A wrapper around libc::malloc, aborting on out-of-memory
pub unsafe fn malloc_raw(size: uint) -> *c_void {
#[fixed_stack_segment]; #[inline(never)];
let p = malloc(size as size_t);
if p.is_null() {
// we need a non-allocating way to print an error here
@ -48,8 +45,6 @@ pub unsafe fn malloc_raw(size: uint) -> *c_void {
/// A wrapper around libc::realloc, aborting on out-of-memory
pub unsafe fn realloc_raw(ptr: *mut c_void, size: uint) -> *mut c_void {
#[fixed_stack_segment]; #[inline(never)];
let p = realloc(ptr, size as size_t);
if p.is_null() {
// we need a non-allocating way to print an error here
@ -100,8 +95,6 @@ pub unsafe fn exchange_free_(ptr: *c_char) {
}
pub unsafe fn exchange_free(ptr: *c_char) {
#[fixed_stack_segment]; #[inline(never)];
free(ptr as *c_void);
}

View File

@ -98,7 +98,6 @@ impl FileDesc {
}
impl Reader for FileDesc {
#[fixed_stack_segment] #[inline(never)]
fn read(&mut self, buf: &mut [u8]) -> Option<uint> {
#[cfg(windows)] type rlen = libc::c_uint;
#[cfg(not(windows))] type rlen = libc::size_t;
@ -121,7 +120,6 @@ impl Reader for FileDesc {
}
impl Writer for FileDesc {
#[fixed_stack_segment] #[inline(never)]
fn write(&mut self, buf: &[u8]) {
#[cfg(windows)] type wlen = libc::c_uint;
#[cfg(not(windows))] type wlen = libc::size_t;
@ -137,7 +135,6 @@ impl Writer for FileDesc {
}
impl Drop for FileDesc {
#[fixed_stack_segment] #[inline(never)]
fn drop(&mut self) {
if self.close_on_drop {
unsafe { libc::close(self.fd); }
@ -158,7 +155,6 @@ impl CFile {
}
impl Reader for CFile {
#[fixed_stack_segment] #[inline(never)]
fn read(&mut self, buf: &mut [u8]) -> Option<uint> {
let ret = do keep_going(buf) |buf, len| {
unsafe {
@ -176,14 +172,12 @@ impl Reader for CFile {
}
}
#[fixed_stack_segment] #[inline(never)]
fn eof(&mut self) -> bool {
unsafe { libc::feof(self.file) != 0 }
}
}
impl Writer for CFile {
#[fixed_stack_segment] #[inline(never)]
fn write(&mut self, buf: &[u8]) {
let ret = do keep_going(buf) |buf, len| {
unsafe {
@ -196,7 +190,6 @@ impl Writer for CFile {
}
}
#[fixed_stack_segment] #[inline(never)]
fn flush(&mut self) {
if unsafe { libc::fflush(self.file) } < 0 {
raise_error();
@ -205,7 +198,6 @@ impl Writer for CFile {
}
impl Seek for CFile {
#[fixed_stack_segment] #[inline(never)]
fn tell(&self) -> u64 {
let ret = unsafe { libc::ftell(self.file) };
if ret < 0 {
@ -214,7 +206,6 @@ impl Seek for CFile {
return ret as u64;
}
#[fixed_stack_segment] #[inline(never)]
fn seek(&mut self, pos: i64, style: SeekStyle) {
let whence = match style {
SeekSet => libc::SEEK_SET,
@ -228,7 +219,6 @@ impl Seek for CFile {
}
impl Drop for CFile {
#[fixed_stack_segment] #[inline(never)]
fn drop(&mut self) {
unsafe { libc::fclose(self.file); }
}
@ -242,7 +232,6 @@ mod tests {
use rt::io::{io_error, SeekSet};
use super::*;
#[test] #[fixed_stack_segment]
#[ignore(cfg(target_os = "freebsd"))] // hmm, maybe pipes have a tiny buffer
fn test_file_desc() {
// Run this test with some pipes so we don't have to mess around with
@ -278,7 +267,6 @@ mod tests {
}
}
#[test] #[fixed_stack_segment]
#[ignore(cfg(windows))] // apparently windows doesn't like tmpfile
fn test_cfile() {
unsafe {
@ -358,7 +346,6 @@ mod old_os {
#[cfg(unix)]
/// Indicates whether a path represents a directory
pub fn path_is_dir(p: &Path) -> bool {
#[fixed_stack_segment]; #[inline(never)];
unsafe {
do p.with_c_str |buf| {
rustrt::rust_path_is_dir(buf) != 0 as c_int
@ -369,7 +356,6 @@ mod old_os {
#[cfg(windows)]
pub fn path_is_dir(p: &Path) -> bool {
#[fixed_stack_segment]; #[inline(never)];
unsafe {
do os::win32::as_utf16_p(p.as_str().unwrap()) |buf| {
rustrt::rust_path_is_dir_u16(buf) != 0 as c_int
@ -380,7 +366,6 @@ mod old_os {
#[cfg(unix)]
/// Indicates whether a path exists
pub fn path_exists(p: &Path) -> bool {
#[fixed_stack_segment]; #[inline(never)];
unsafe {
do p.with_c_str |buf| {
rustrt::rust_path_exists(buf) != 0 as c_int
@ -390,7 +375,6 @@ mod old_os {
#[cfg(windows)]
pub fn path_exists(p: &Path) -> bool {
#[fixed_stack_segment]; #[inline(never)];
unsafe {
do os::win32::as_utf16_p(p.as_str().unwrap()) |buf| {
rustrt::rust_path_exists_u16(buf) != 0 as c_int
@ -404,7 +388,6 @@ mod old_os {
#[cfg(windows)]
fn mkdir(p: &Path, _mode: c_int) -> bool {
#[fixed_stack_segment]; #[inline(never)];
unsafe {
use os::win32::as_utf16_p;
// FIXME: turn mode into something useful? #2623
@ -417,7 +400,6 @@ mod old_os {
#[cfg(unix)]
fn mkdir(p: &Path, mode: c_int) -> bool {
#[fixed_stack_segment]; #[inline(never)];
do p.with_c_str |buf| {
unsafe {
libc::mkdir(buf, mode as libc::mode_t) == (0 as c_int)
@ -457,7 +439,6 @@ mod old_os {
#[cfg(target_os = "freebsd")]
#[cfg(target_os = "macos")]
unsafe fn get_list(p: &Path) -> ~[Path] {
#[fixed_stack_segment]; #[inline(never)];
use libc::{dirent_t};
use libc::{opendir, readdir, closedir};
extern {
@ -488,7 +469,6 @@ mod old_os {
}
#[cfg(windows)]
unsafe fn get_list(p: &Path) -> ~[Path] {
#[fixed_stack_segment]; #[inline(never)];
use libc::consts::os::extra::INVALID_HANDLE_VALUE;
use libc::{wcslen, free};
use libc::funcs::extra::kernel32::{
@ -568,7 +548,6 @@ mod old_os {
#[cfg(windows)]
fn rmdir(p: &Path) -> bool {
#[fixed_stack_segment]; #[inline(never)];
unsafe {
use os::win32::as_utf16_p;
return do as_utf16_p(p.as_str().unwrap()) |buf| {
@ -579,7 +558,6 @@ mod old_os {
#[cfg(unix)]
fn rmdir(p: &Path) -> bool {
#[fixed_stack_segment]; #[inline(never)];
do p.with_c_str |buf| {
unsafe {
libc::rmdir(buf) == (0 as c_int)
@ -594,7 +572,6 @@ mod old_os {
#[cfg(windows)]
fn unlink(p: &Path) -> bool {
#[fixed_stack_segment]; #[inline(never)];
unsafe {
use os::win32::as_utf16_p;
return do as_utf16_p(p.as_str().unwrap()) |buf| {
@ -605,7 +582,6 @@ mod old_os {
#[cfg(unix)]
fn unlink(p: &Path) -> bool {
#[fixed_stack_segment]; #[inline(never)];
unsafe {
do p.with_c_str |buf| {
libc::unlink(buf) == (0 as c_int)
@ -616,7 +592,6 @@ mod old_os {
/// Renames an existing file or directory
pub fn rename_file(old: &Path, new: &Path) -> bool {
#[fixed_stack_segment]; #[inline(never)];
unsafe {
do old.with_c_str |old_buf| {
do new.with_c_str |new_buf| {
@ -632,7 +607,6 @@ mod old_os {
#[cfg(windows)]
fn do_copy_file(from: &Path, to: &Path) -> bool {
#[fixed_stack_segment]; #[inline(never)];
unsafe {
use os::win32::as_utf16_p;
return do as_utf16_p(from.as_str().unwrap()) |fromp| {
@ -646,7 +620,6 @@ mod old_os {
#[cfg(unix)]
fn do_copy_file(from: &Path, to: &Path) -> bool {
#[fixed_stack_segment]; #[inline(never)];
unsafe {
let istream = do from.with_c_str |fromp| {
do "rb".with_c_str |modebuf| {

View File

@ -69,8 +69,6 @@ impl Process {
stdin: Option<file::fd_t>,
stdout: Option<file::fd_t>,
stderr: Option<file::fd_t>) -> Process {
#[fixed_stack_segment]; #[inline(never)];
let (in_pipe, in_fd) = match stdin {
None => {
let pipe = os::pipe();
@ -208,7 +206,6 @@ impl Process {
#[cfg(windows)]
unsafe fn killpid(pid: pid_t, signal: int) -> Result<(), io::IoError> {
#[fixed_stack_segment]; #[inline(never)];
match signal {
io::process::PleaseExitSignal |
io::process::MustDieSignal => {
@ -226,7 +223,6 @@ impl Process {
#[cfg(not(windows))]
unsafe fn killpid(pid: pid_t, signal: int) -> Result<(), io::IoError> {
#[fixed_stack_segment]; #[inline(never)];
libc::funcs::posix88::signal::kill(pid, signal as c_int);
Ok(())
}
@ -254,8 +250,6 @@ fn spawn_process_os(prog: &str, args: &[~str],
env: Option<~[(~str, ~str)]>,
dir: Option<&Path>,
in_fd: c_int, out_fd: c_int, err_fd: c_int) -> SpawnProcessResult {
#[fixed_stack_segment]; #[inline(never)];
use libc::types::os::arch::extra::{DWORD, HANDLE, STARTUPINFO};
use libc::consts::os::extra::{
TRUE, FALSE,
@ -439,8 +433,6 @@ fn spawn_process_os(prog: &str, args: &[~str],
env: Option<~[(~str, ~str)]>,
dir: Option<&Path>,
in_fd: c_int, out_fd: c_int, err_fd: c_int) -> SpawnProcessResult {
#[fixed_stack_segment]; #[inline(never)];
use libc::funcs::posix88::unistd::{fork, dup2, close, chdir, execvp};
use libc::funcs::bsd44::getdtablesize;
@ -455,7 +447,7 @@ fn spawn_process_os(prog: &str, args: &[~str],
unsafe fn set_environ(_envp: *c_void) {}
#[cfg(target_os = "macos")]
unsafe fn set_environ(envp: *c_void) {
externfn!(fn _NSGetEnviron() -> *mut *c_void);
extern { fn _NSGetEnviron() -> *mut *c_void; }
*_NSGetEnviron() = envp;
}
@ -603,7 +595,6 @@ fn with_dirp<T>(d: Option<&Path>, cb: &fn(*libc::c_char) -> T) -> T {
#[cfg(windows)]
fn free_handle(handle: *()) {
#[fixed_stack_segment]; #[inline(never)];
unsafe {
libc::funcs::extra::kernel32::CloseHandle(cast::transmute(handle));
}
@ -629,8 +620,6 @@ fn waitpid(pid: pid_t) -> int {
#[cfg(windows)]
fn waitpid_os(pid: pid_t) -> int {
#[fixed_stack_segment]; #[inline(never)];
use libc::types::os::arch::extra::DWORD;
use libc::consts::os::extra::{
SYNCHRONIZE,
@ -676,8 +665,6 @@ fn waitpid(pid: pid_t) -> int {
#[cfg(unix)]
fn waitpid_os(pid: pid_t) -> int {
#[fixed_stack_segment]; #[inline(never)];
use libc::funcs::posix01::wait::*;
#[cfg(target_os = "linux")]

View File

@ -154,7 +154,6 @@ mod test {
// kill is only available on Unixes
#[cfg(unix)]
#[fixed_stack_segment]
fn sigint() {
unsafe {
libc::funcs::posix88::signal::kill(libc::getpid(), libc::SIGINT);

View File

@ -69,7 +69,6 @@ enum StdSource {
File(~RtioFileStream),
}
#[fixed_stack_segment] #[inline(never)]
fn src<T>(fd: libc::c_int, readable: bool, f: &fn(StdSource) -> T) -> T {
do with_local_io |io| {
let fd = unsafe { libc::dup(fd) };
@ -91,7 +90,6 @@ fn src<T>(fd: libc::c_int, readable: bool, f: &fn(StdSource) -> T) -> T {
/// Creates a new non-blocking handle to the stdin of the current process.
///
/// See `stdout()` for notes about this function.
#[fixed_stack_segment] #[inline(never)]
pub fn stdin() -> StdReader {
do src(libc::STDIN_FILENO, true) |src| { StdReader { inner: src } }
}

View File

@ -26,8 +26,6 @@ use tls = rt::thread_local_storage;
static mut RT_TLS_KEY: tls::Key = -1;
/// Initialize the TLS key. Other ops will fail if this isn't executed first.
#[fixed_stack_segment]
#[inline(never)]
pub fn init_tls_key() {
unsafe {
rust_initialize_rt_tls_key(&mut RT_TLS_KEY);

View File

@ -135,7 +135,6 @@ fn update_entry(dirs: &[LogDirective], entry: &ModEntry) -> u32 {
if longest_match >= 0 { return 1; } else { return 0; }
}
#[fixed_stack_segment] #[inline(never)]
/// Set log level for every entry in crate_map according to the sepecification
/// in settings
fn update_log_settings(crate_map: &CrateMap, settings: ~str) {

View File

@ -463,8 +463,6 @@ pub fn in_green_task_context() -> bool {
}
pub fn new_event_loop() -> ~rtio::EventLoop {
#[fixed_stack_segment]; #[allow(cstack)];
match crate_map::get_crate_map() {
None => {}
Some(map) => {

View File

@ -853,7 +853,6 @@ fn new_sched_rng() -> XorShiftRng {
XorShiftRng::new()
}
#[cfg(unix)]
#[fixed_stack_segment] #[inline(never)]
fn new_sched_rng() -> XorShiftRng {
use libc;
use mem;

View File

@ -21,8 +21,6 @@ pub struct StackSegment {
impl StackSegment {
pub fn new(size: uint) -> StackSegment {
#[fixed_stack_segment]; #[inline(never)];
unsafe {
// Crate a block of uninitialized values
let mut stack = vec::with_capacity(size);
@ -54,8 +52,6 @@ impl StackSegment {
impl Drop for StackSegment {
fn drop(&mut self) {
#[fixed_stack_segment]; #[inline(never)];
unsafe {
// XXX: Using the FFI to call a C macro. Slow
rust_valgrind_stack_deregister(self.valgrind_id);

View File

@ -509,7 +509,6 @@ impl Unwinder {
}
extern {
#[rust_stack]
fn rust_try(f: extern "C" fn(*c_void, *c_void),
code: *c_void,
data: *c_void) -> uintptr_t;
@ -517,8 +516,6 @@ impl Unwinder {
}
pub fn begin_unwind(&mut self, cause: ~Any) -> ! {
#[fixed_stack_segment]; #[inline(never)];
self.unwinding = true;
self.cause = Some(cause);
unsafe {
@ -537,9 +534,8 @@ impl Unwinder {
/// truly consider it to be stack overflow rather than allocating a new stack.
#[no_mangle] // - this is called from C code
#[no_split_stack] // - it would be sad for this function to trigger __morestack
#[doc(hidden)] // XXX: this function shouldn't have to be `pub` to get exported
// so it can be linked against, we should have a better way
// of specifying that.
#[doc(hidden)] // - Function must be `pub` to get exported, but it's
// irrelevant for documentation purposes.
pub extern "C" fn rust_stack_exhausted() {
use rt::in_green_task_context;
use rt::task::Task;

View File

@ -143,8 +143,6 @@ mod darwin_fd_limit {
static RLIMIT_NOFILE: libc::c_int = 8;
pub unsafe fn raise_fd_limit() {
#[fixed_stack_segment]; #[inline(never)];
// The strategy here is to fetch the current resource limits, read the kern.maxfilesperproc
// sysctl value, and bump the soft resource limit for maxfiles up to the sysctl value.
use ptr::{to_unsafe_ptr, to_mut_unsafe_ptr, mut_null};
@ -362,7 +360,6 @@ pub fn cleanup_task(mut task: ~Task) {
}
/// Get a port number, starting at 9600, for use in tests
#[fixed_stack_segment] #[inline(never)]
pub fn next_test_port() -> u16 {
unsafe {
return rust_dbg_next_port(base_port() as libc::uintptr_t) as u16;
@ -373,7 +370,6 @@ pub fn next_test_port() -> u16 {
}
/// Get a temporary path which could be the location of a unix socket
#[fixed_stack_segment] #[inline(never)]
pub fn next_test_unix() -> Path {
if cfg!(unix) {
os::tmpdir().join(rand::task_rng().gen_ascii_str(20))

View File

@ -68,8 +68,6 @@ impl Thread {
#[cfg(windows)]
fn native_thread_create(thread_start: extern "C" fn(*libc::c_void) -> rust_thread_return,
tramp: ~~fn()) -> rust_thread {
#[fixed_stack_segment];
unsafe {
let ptr: *mut libc::c_void = cast::transmute(tramp);
CreateThread(ptr::mut_null(), DEFAULT_STACK_SIZE, thread_start, ptr, 0, ptr::mut_null())
@ -78,7 +76,6 @@ fn native_thread_create(thread_start: extern "C" fn(*libc::c_void) -> rust_threa
#[cfg(windows)]
fn native_thread_join(native: rust_thread) {
#[fixed_stack_segment];
use libc::consts::os::extra::INFINITE;
unsafe { WaitForSingleObject(native, INFINITE); }
}
@ -86,8 +83,6 @@ fn native_thread_join(native: rust_thread) {
#[cfg(unix)]
fn native_thread_create(thread_start: extern "C" fn(*libc::c_void) -> rust_thread_return,
tramp: ~~fn()) -> rust_thread {
#[fixed_stack_segment];
use unstable::intrinsics;
let mut native: libc::pthread_t = unsafe { intrinsics::uninit() };
@ -107,13 +102,11 @@ fn native_thread_create(thread_start: extern "C" fn(*libc::c_void) -> rust_threa
#[cfg(unix)]
fn native_thread_join(native: rust_thread) {
#[fixed_stack_segment];
unsafe { assert!(pthread_join(native, ptr::null()) == 0) }
}
impl Drop for Thread {
fn drop(&mut self) {
#[fixed_stack_segment]; #[inline(never)];
assert!(self.joined);
}
}

View File

@ -20,8 +20,6 @@ use libc::types::os::arch::extra::{DWORD, LPVOID, BOOL};
pub type Key = pthread_key_t;
#[cfg(unix)]
#[fixed_stack_segment]
#[inline(never)]
pub unsafe fn create(key: &mut Key) {
assert_eq!(0, pthread_key_create(key, null()));
}
@ -49,20 +47,7 @@ type pthread_key_t = ::libc::c_uint;
#[cfg(unix)]
extern {
fn pthread_key_create(key: *mut pthread_key_t, dtor: *u8) -> c_int;
// This function is a very cheap operation on both osx and unix. On osx, it
// turns out it's just three instructions, and on unix it's a cheap function
// which only uses a very small amount of stack.
//
// This is not marked as such because we think it has a small stack, but
// rather we would like to be able to fetch information from
// thread-local-storage when a task is running very low on its stack budget.
// For example, this is invoked whenever stack overflow is detected, and we
// obviously have very little budget to deal with (certainly not anything
// close to a fixed_stack_segment)
#[rust_stack]
fn pthread_getspecific(key: pthread_key_t) -> *mut c_void;
#[rust_stack]
fn pthread_setspecific(key: pthread_key_t, value: *mut c_void) -> c_int;
}
@ -70,8 +55,6 @@ extern {
pub type Key = DWORD;
#[cfg(windows)]
#[fixed_stack_segment]
#[inline(never)]
pub unsafe fn create(key: &mut Key) {
static TLS_OUT_OF_INDEXES: DWORD = 0xFFFFFFFF;
*key = TlsAlloc();
@ -91,13 +74,7 @@ pub unsafe fn get(key: Key) -> *mut c_void {
#[cfg(windows)]
extern "system" {
fn TlsAlloc() -> DWORD;
// See the reasoning in pthread_getspecific as to why this has the
// 'rust_stack' attribute, as this function was also verified to only
// require a small amount of stack.
#[rust_stack]
fn TlsGetValue(dwTlsIndex: DWORD) -> LPVOID;
#[rust_stack]
fn TlsSetValue(dwTlsIndex: DWORD, lpTlsvalue: LPVOID) -> BOOL;
}

View File

@ -24,8 +24,6 @@ pub static ENFORCE_SANITY: bool = true || !cfg!(rtopt) || cfg!(rtdebug) || cfg!(
/// Get the number of cores available
pub fn num_cpus() -> uint {
#[fixed_stack_segment]; #[inline(never)];
unsafe {
return rust_get_num_cpus();
}
@ -146,7 +144,6 @@ memory and partly incapable of presentation to others.",
abort();
fn abort() -> ! {
#[fixed_stack_segment]; #[inline(never)];
unsafe { libc::abort() }
}
}

View File

@ -296,7 +296,6 @@ impl Process {
*
* The process's exit code
*/
#[fixed_stack_segment] #[inline(never)]
pub fn process_status(prog: &str, args: &[~str]) -> int {
let mut prog = Process::new(prog, args, ProcessOptions {
env: None,

View File

@ -1145,12 +1145,14 @@ fn test_spawn_sched_childs_on_default_sched() {
mod testrt {
use libc;
externfn!(fn rust_dbg_lock_create() -> *libc::c_void)
externfn!(fn rust_dbg_lock_destroy(lock: *libc::c_void))
externfn!(fn rust_dbg_lock_lock(lock: *libc::c_void))
externfn!(fn rust_dbg_lock_unlock(lock: *libc::c_void))
externfn!(fn rust_dbg_lock_wait(lock: *libc::c_void))
externfn!(fn rust_dbg_lock_signal(lock: *libc::c_void))
extern {
pub fn rust_dbg_lock_create() -> *libc::c_void;
pub fn rust_dbg_lock_destroy(lock: *libc::c_void);
pub fn rust_dbg_lock_lock(lock: *libc::c_void);
pub fn rust_dbg_lock_unlock(lock: *libc::c_void);
pub fn rust_dbg_lock_wait(lock: *libc::c_void);
pub fn rust_dbg_lock_signal(lock: *libc::c_void);
}
}
#[test]

View File

@ -144,21 +144,16 @@ pub mod dl {
use result::*;
pub unsafe fn open_external(filename: &path::Path) -> *libc::c_void {
#[fixed_stack_segment]; #[inline(never)];
do filename.with_c_str |raw_name| {
dlopen(raw_name, Lazy as libc::c_int)
}
}
pub unsafe fn open_internal() -> *libc::c_void {
#[fixed_stack_segment]; #[inline(never)];
dlopen(ptr::null(), Lazy as libc::c_int)
}
pub fn check_for_errors_in<T>(f: &fn()->T) -> Result<T, ~str> {
#[fixed_stack_segment]; #[inline(never)];
unsafe {
// dlerror isn't thread safe, so we need to lock around this entire
// sequence. `atomically` asserts that we don't do anything that
@ -184,13 +179,9 @@ pub mod dl {
}
pub unsafe fn symbol(handle: *libc::c_void, symbol: *libc::c_char) -> *libc::c_void {
#[fixed_stack_segment]; #[inline(never)];
dlsym(handle, symbol)
}
pub unsafe fn close(handle: *libc::c_void) {
#[fixed_stack_segment]; #[inline(never)];
dlclose(handle); ()
}
@ -225,21 +216,18 @@ pub mod dl {
use result::*;
pub unsafe fn open_external(filename: &path::Path) -> *libc::c_void {
#[fixed_stack_segment]; #[inline(never)];
do os::win32::as_utf16_p(filename.as_str().unwrap()) |raw_name| {
LoadLibraryW(raw_name)
}
}
pub unsafe fn open_internal() -> *libc::c_void {
#[fixed_stack_segment]; #[inline(never)];
let handle = ptr::null();
GetModuleHandleExW(0 as libc::DWORD, ptr::null(), &handle as **libc::c_void);
handle
}
pub fn check_for_errors_in<T>(f: &fn()->T) -> Result<T, ~str> {
#[fixed_stack_segment]; #[inline(never)];
unsafe {
do atomically {
SetLastError(0);
@ -257,11 +245,9 @@ pub mod dl {
}
pub unsafe fn symbol(handle: *libc::c_void, symbol: *libc::c_char) -> *libc::c_void {
#[fixed_stack_segment]; #[inline(never)];
GetProcAddress(handle, symbol)
}
pub unsafe fn close(handle: *libc::c_void) {
#[fixed_stack_segment]; #[inline(never)];
FreeLibrary(handle); ()
}

View File

@ -369,28 +369,16 @@ extern "rust-intrinsic" {
pub fn powif32(a: f32, x: i32) -> f32;
pub fn powif64(a: f64, x: i32) -> f64;
// the following kill the stack canary without
// `fixed_stack_segment`. This possibly only affects the f64
// variants, but it's hard to be sure since it seems to only
// occur with fairly specific arguments.
#[fixed_stack_segment]
pub fn sinf32(x: f32) -> f32;
#[fixed_stack_segment]
pub fn sinf64(x: f64) -> f64;
#[fixed_stack_segment]
pub fn cosf32(x: f32) -> f32;
#[fixed_stack_segment]
pub fn cosf64(x: f64) -> f64;
#[fixed_stack_segment]
pub fn powf32(a: f32, x: f32) -> f32;
#[fixed_stack_segment]
pub fn powf64(a: f64, x: f64) -> f64;
#[fixed_stack_segment]
pub fn expf32(x: f32) -> f32;
#[fixed_stack_segment]
pub fn expf64(x: f64) -> f64;
pub fn exp2f32(x: f32) -> f32;

View File

@ -72,7 +72,6 @@ fn test_run_in_bare_thread_exchange() {
/// can't run correctly un-altered. Valgrind is there to help
/// you notice weirdness in normal, un-doctored code paths!
pub fn running_on_valgrind() -> bool {
#[fixed_stack_segment]; #[inline(never)];
unsafe { rust_running_on_valgrind() != 0 }
}

View File

@ -475,12 +475,14 @@ impl<T:Send> Exclusive<T> {
}
}
externfn!(fn rust_create_little_lock() -> rust_little_lock)
externfn!(fn rust_destroy_little_lock(lock: rust_little_lock))
externfn!(fn rust_lock_little_lock(lock: rust_little_lock))
externfn!(fn rust_unlock_little_lock(lock: rust_little_lock))
externfn!(fn rust_signal_little_lock(lock: rust_little_lock))
externfn!(fn rust_wait_little_lock(lock: rust_little_lock))
extern {
fn rust_create_little_lock() -> rust_little_lock;
fn rust_destroy_little_lock(lock: rust_little_lock);
fn rust_lock_little_lock(lock: rust_little_lock);
fn rust_unlock_little_lock(lock: rust_little_lock);
fn rust_signal_little_lock(lock: rust_little_lock);
fn rust_wait_little_lock(lock: rust_little_lock);
}
#[cfg(test)]
mod tests {

View File

@ -201,7 +201,6 @@ fn print_maybe_styled(msg: &str, color: term::attr::Attr) {
let stderr = @mut io::stderr() as @mut io::Writer;
fn is_stderr_screen() -> bool {
#[fixed_stack_segment];
use std::libc;
unsafe { libc::isatty(libc::STDERR_FILENO) != 0 }
}

View File

@ -959,84 +959,6 @@ pub fn std_macros() -> @str {
pub static $name: ::std::local_data::Key<$ty> = &::std::local_data::Key;
)
)
/// externfn! declares a wrapper for an external function.
/// It is intended to be used like:
///
/// externfn!(#[nolink]
/// fn memcmp(cx: *u8, ct: *u8, n: u32) -> u32)
///
/// Due to limitations in the macro parser, this pattern must be
/// implemented with 4 distinct patterns (with attrs / without
/// attrs CROSS with args / without ARGS).
///
/// Also, this macro grammar allows for any number of return types
/// because I couldn't figure out the syntax to specify at most one.
macro_rules! externfn(
(fn $name:ident () $(-> $ret_ty:ty),*) => (
pub unsafe fn $name() $(-> $ret_ty),* {
// Note: to avoid obscure bug in macros, keep these
// attributes *internal* to the fn
#[fixed_stack_segment];
#[inline(never)];
#[allow(missing_doc)];
return $name();
extern {
fn $name() $(-> $ret_ty),*;
}
}
);
(fn $name:ident ($($arg_name:ident : $arg_ty:ty),*) $(-> $ret_ty:ty),*) => (
pub unsafe fn $name($($arg_name : $arg_ty),*) $(-> $ret_ty),* {
// Note: to avoid obscure bug in macros, keep these
// attributes *internal* to the fn
#[fixed_stack_segment];
#[inline(never)];
#[allow(missing_doc)];
return $name($($arg_name),*);
extern {
fn $name($($arg_name : $arg_ty),*) $(-> $ret_ty),*;
}
}
);
($($attrs:attr)* fn $name:ident () $(-> $ret_ty:ty),*) => (
pub unsafe fn $name() $(-> $ret_ty),* {
// Note: to avoid obscure bug in macros, keep these
// attributes *internal* to the fn
#[fixed_stack_segment];
#[inline(never)];
#[allow(missing_doc)];
return $name();
$($attrs)*
extern {
fn $name() $(-> $ret_ty),*;
}
}
);
($($attrs:attr)* fn $name:ident ($($arg_name:ident : $arg_ty:ty),*) $(-> $ret_ty:ty),*) => (
pub unsafe fn $name($($arg_name : $arg_ty),*) $(-> $ret_ty),* {
// Note: to avoid obscure bug in macros, keep these
// attributes *internal* to the fn
#[fixed_stack_segment];
#[inline(never)];
#[allow(missing_doc)];
return $name($($arg_name),*);
$($attrs)*
extern {
fn $name($($arg_name : $arg_ty),*) $(-> $ret_ty),*;
}
}
)
)
}"#
}

View File

@ -22,6 +22,8 @@
#[crate_type = "lib"];
#[feature(macro_rules, globs, managed_boxes)];
#[allow(unrecognized_lint)]; // NOTE: remove after the next snapshot
#[allow(cstack)]; // NOTE: remove after the next snapshot.
extern mod extra;

View File

@ -25,7 +25,6 @@ pub mod rustrt {
}
}
#[fixed_stack_segment] #[inline(never)]
pub fn fact(n: uint) -> uint {
unsafe {
info!("n = {}", n);

View File

@ -91,7 +91,6 @@ fn vector<M: MutableMap<uint, uint>>(map: &mut M, n_keys: uint, dist: &[uint]) {
}
}
#[fixed_stack_segment]
fn main() {
let args = os::args();
let n_keys = {

View File

@ -91,7 +91,6 @@ fn fannkuch_redux(n: i32) -> i32 {
}
}
#[fixed_stack_segment]
fn main() {
let n: i32 = FromStr::from_str(os::args()[1]).unwrap();
println!("Pfannkuchen({}) = {}", n as int, fannkuch_redux(n) as int);

View File

@ -184,7 +184,6 @@ impl RandomFasta {
}
}
#[fixed_stack_segment]
fn main() {
let n: uint = FromStr::from_str(os::args()[1]).unwrap();

View File

@ -243,8 +243,6 @@ fn read_stdin() -> ~[u8] {
}
}
#[inline(never)]
#[fixed_stack_segment]
fn generate_frequencies(frequencies: &mut Table,
mut input: &[u8],
frame: i32) {
@ -264,8 +262,6 @@ fn generate_frequencies(frequencies: &mut Table,
}
}
#[inline(never)]
#[fixed_stack_segment]
fn print_frequencies(frequencies: &Table, frame: i32) {
let mut vector = ~[];
for frequencies.each |entry| {
@ -289,7 +285,6 @@ fn print_occurrences(frequencies: &mut Table, occurrence: &'static str) {
frequencies.lookup(Code::pack(occurrence), PrintCallback(occurrence))
}
#[fixed_stack_segment]
fn main() {
let input = read_stdin();

View File

@ -8,7 +8,6 @@ use std::os;
static ITER: uint = 50;
static LIMIT: f64 = 2.0;
#[fixed_stack_segment]
fn main() {
unsafe {
let w: i32 = FromStr::from_str(os::args()[1]).unwrap();

View File

@ -161,7 +161,6 @@ fn pidigits(n: u32) {
}
}
#[fixed_stack_segment]
fn main() {
let n: u32 = FromStr::from_str(os::args()[1]).get();
pidigits(n);

View File

@ -90,7 +90,6 @@ static COMPLEMENTS: [u8, ..256] = [
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
];
#[fixed_stack_segment]
fn main() {
unsafe {
let mode = "r";

View File

@ -52,7 +52,6 @@ fn mult_AtAv(v: &mut [f64], out: &mut [f64], tmp: &mut [f64]) {
mult_Atv(tmp, out);
}
#[fixed_stack_segment]
fn main() {
let n: uint = FromStr::from_str(os::args()[1]).unwrap();
let mut u = vec::from_elem(n, 1f64);

View File

@ -1,23 +0,0 @@
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
extern fn f() {
}
extern fn call1() {
f(); // OK from another extern fn!
}
fn call2() {
f(); //~ ERROR invoking non-Rust fn
}
fn main() {}

View File

@ -1,24 +0,0 @@
// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
extern {
fn rust_get_test_int() -> std::libc::intptr_t;
}
trait A {
fn foo() {
unsafe {
rust_get_test_int(); //~ ERROR invoking non-Rust fn
}
}
}
fn main() {
}

View File

@ -10,7 +10,6 @@
// Exercise the unused_unsafe attribute in some positive and negative cases
#[allow(cstack)];
#[deny(unused_unsafe)];
mod foo {

View File

@ -18,7 +18,6 @@ extern {
extern "C" fn bar(f: int, x: u8) {}
#[fixed_stack_segment]
fn main() {
unsafe {
foo(); //~ ERROR: this function takes at least 2 parameters but 0 parameters were supplied

View File

@ -14,7 +14,6 @@ extern mod anonexternmod;
use anonexternmod::rust_get_test_int;
#[fixed_stack_segment]
pub fn main() {
unsafe {
rust_get_test_int();

View File

@ -15,7 +15,6 @@ extern {
fn rust_get_test_int() -> libc::intptr_t;
}
#[fixed_stack_segment]
pub fn main() {
unsafe {
let _ = rust_get_test_int();

View File

@ -18,12 +18,10 @@ mod libc {
}
}
#[fixed_stack_segment]
fn atol(s: ~str) -> int {
s.with_c_str(|x| unsafe { libc::atol(x) as int })
}
#[fixed_stack_segment]
fn atoll(s: ~str) -> i64 {
s.with_c_str(|x| unsafe { libc::atoll(x) as i64 })
}

View File

@ -60,8 +60,6 @@ fn test_destroy_actually_kills(force: bool) {
#[cfg(windows)]
fn process_exists(pid: libc::pid_t) -> bool {
#[fixed_stack_segment];
use std::libc::types::os::arch::extra::DWORD;
use std::libc::funcs::extra::kernel32::{CloseHandle, GetExitCodeProcess, OpenProcess};
use std::libc::consts::os::extra::{FALSE, PROCESS_QUERY_INFORMATION, STILL_ACTIVE };

View File

@ -28,7 +28,6 @@ extern fn cb(data: libc::uintptr_t) -> libc::uintptr_t {
}
}
#[fixed_stack_segment]
fn count(n: uint) -> uint {
unsafe {
info!("n = {}", n);

View File

@ -29,7 +29,6 @@ extern fn cb(data: libc::uintptr_t) -> libc::uintptr_t {
}
}
#[fixed_stack_segment] #[inline(never)]
fn count(n: uint) -> uint {
unsafe {
info!("n = {}", n);

View File

@ -13,8 +13,6 @@
extern fn f(x: uint) -> uint { x * 2 }
pub fn main() {
#[fixed_stack_segment];
let x = f(22);
assert_eq!(x, 44);
}

View File

@ -28,7 +28,6 @@ extern fn cb(data: libc::uintptr_t) -> libc::uintptr_t {
}
}
#[fixed_stack_segment] #[inline(never)]
fn fact(n: uint) -> uint {
unsafe {
info!("n = {}", n);

View File

@ -33,7 +33,6 @@ extern fn cb(data: libc::uintptr_t) -> libc::uintptr_t {
}
}
#[fixed_stack_segment] #[inline(never)]
fn count(n: uint) -> uint {
unsafe {
info!("n = {}", n);

View File

@ -13,7 +13,6 @@
extern mod externcallback(vers = "0.1");
#[fixed_stack_segment] #[inline(never)]
fn fact(n: uint) -> uint {
unsafe {
info!("n = {}", n);

View File

@ -22,7 +22,6 @@ extern {
pub fn rust_dbg_extern_identity_TwoU16s(v: TwoU16s) -> TwoU16s;
}
#[fixed_stack_segment] #[inline(never)]
pub fn main() {
unsafe {
let x = TwoU16s {one: 22, two: 23};

View File

@ -20,7 +20,6 @@ extern {
pub fn rust_dbg_extern_identity_TwoU32s(v: TwoU32s) -> TwoU32s;
}
#[fixed_stack_segment] #[inline(never)]
pub fn main() {
unsafe {
let x = TwoU32s {one: 22, two: 23};

View File

@ -20,7 +20,6 @@ extern {
pub fn rust_dbg_extern_identity_TwoU64s(u: TwoU64s) -> TwoU64s;
}
#[fixed_stack_segment] #[inline(never)]
pub fn main() {
unsafe {
let x = TwoU64s {one: 22, two: 23};

View File

@ -25,7 +25,6 @@ extern {
pub fn rust_dbg_extern_identity_TwoU64s(v: TwoU64s) -> TwoU64s;
}
#[fixed_stack_segment] #[inline(never)]
pub fn main() {
unsafe {
let x = TwoU64s {one: 22, two: 23};

View File

@ -22,7 +22,6 @@ extern {
pub fn rust_dbg_extern_identity_TwoU8s(v: TwoU8s) -> TwoU8s;
}
#[fixed_stack_segment] #[inline(never)]
pub fn main() {
unsafe {
let x = TwoU8s {one: 22, two: 23};

View File

@ -14,7 +14,6 @@ extern {
pub fn rust_dbg_extern_identity_u8(v: u8) -> u8;
}
#[fixed_stack_segment] #[inline(never)]
pub fn main() {
unsafe {
assert_eq!(22_u8, rust_dbg_extern_identity_u8(22_u8));

View File

@ -12,7 +12,6 @@ extern {
pub fn rust_dbg_extern_identity_double(v: f64) -> f64;
}
#[fixed_stack_segment] #[inline(never)]
pub fn main() {
unsafe {
assert_eq!(22.0_f64, rust_dbg_extern_identity_double(22.0_f64));

View File

@ -14,7 +14,6 @@ extern {
pub fn rust_dbg_extern_identity_u32(v: u32) -> u32;
}
#[fixed_stack_segment] #[inline(never)]
pub fn main() {
unsafe {
assert_eq!(22_u32, rust_dbg_extern_identity_u32(22_u32));

View File

@ -14,7 +14,6 @@ extern {
pub fn rust_dbg_extern_identity_u64(v: u64) -> u64;
}
#[fixed_stack_segment] #[inline(never)]
pub fn main() {
unsafe {
assert_eq!(22_u64, rust_dbg_extern_identity_u64(22_u64));

View File

@ -16,7 +16,6 @@ extern {
pub fn rust_dbg_extern_return_TwoU16s() -> TwoU16s;
}
#[fixed_stack_segment] #[inline(never)]
pub fn main() {
unsafe {
let y = rust_dbg_extern_return_TwoU16s();

View File

@ -16,7 +16,6 @@ extern {
pub fn rust_dbg_extern_return_TwoU32s() -> TwoU32s;
}
#[fixed_stack_segment] #[inline(never)]
pub fn main() {
unsafe {
let y = rust_dbg_extern_return_TwoU32s();

View File

@ -18,7 +18,6 @@ extern {
pub fn rust_dbg_extern_return_TwoU64s() -> TwoU64s;
}
#[fixed_stack_segment] #[inline(never)]
pub fn main() {
unsafe {
let y = rust_dbg_extern_return_TwoU64s();

View File

@ -16,7 +16,6 @@ extern {
pub fn rust_dbg_extern_return_TwoU8s() -> TwoU8s;
}
#[fixed_stack_segment] #[inline(never)]
pub fn main() {
unsafe {
let y = rust_dbg_extern_return_TwoU8s();

View File

@ -33,7 +33,6 @@ extern fn cb(data: libc::uintptr_t) -> libc::uintptr_t {
}
}
#[fixed_stack_segment] #[inline(never)]
fn count(n: uint) -> uint {
unsafe {
rustrt::rust_dbg_call(cb, n)

View File

@ -29,7 +29,6 @@ extern fn cb(data: libc::uintptr_t) -> libc::uintptr_t {
}
}
#[fixed_stack_segment] #[inline(never)]
fn count(n: uint) -> uint {
unsafe {
task::deschedule();

View File

@ -2,8 +2,10 @@ use std::cast;
use std::libc;
use std::unstable::run_in_bare_thread;
externfn!(fn rust_dbg_call(cb: extern "C" fn(libc::uintptr_t),
data: libc::uintptr_t) -> libc::uintptr_t)
extern {
fn rust_dbg_call(cb: extern "C" fn(libc::uintptr_t),
data: libc::uintptr_t) -> libc::uintptr_t;
}
pub fn main() {
unsafe {

View File

@ -29,7 +29,6 @@ mod rustrt2 {
}
}
#[fixed_stack_segment] #[inline(never)]
pub fn main() {
unsafe {
rustrt1::rust_get_test_int();

View File

@ -20,7 +20,6 @@ mod libc {
}
}
#[fixed_stack_segment] #[inline(never)]
fn strlen(str: ~str) -> uint {
// C string is terminated with a zero
do str.with_c_str |buf| {

View File

@ -18,7 +18,6 @@ mod rustrt {
}
}
#[fixed_stack_segment] #[inline(never)]
pub fn main() {
unsafe {
rustrt::rust_get_test_int();

View File

@ -17,7 +17,6 @@
extern mod foreign_lib;
#[fixed_stack_segment] #[inline(never)]
pub fn main() {
unsafe {
let _foo = foreign_lib::rustrt::rust_get_test_int();

Some files were not shown because too many files have changed in this diff Show More