提交 ca71c6ec 编写于 作者: P Patrick Walton

librustc: Make all external functions unsafe. r=tjc

上级 d97ab788
......@@ -118,14 +118,16 @@ fn writeclose(fd: c_int, s: Option<~str>) {
}
fn readclose(fd: c_int) -> ~str {
// Copied from run::program_output
let file = os::fdopen(fd);
let reader = io::FILE_reader(file, false);
let mut buf = ~"";
while !reader.eof() {
let bytes = reader.read_bytes(4096u);
str::push_str(&mut buf, str::from_bytes(bytes));
unsafe {
// Copied from run::program_output
let file = os::fdopen(fd);
let reader = io::FILE_reader(file, false);
let mut buf = ~"";
while !reader.eof() {
let bytes = reader.read_bytes(4096u);
str::push_str(&mut buf, str::from_bytes(bytes));
}
os::fclose(file);
return buf;
}
os::fclose(file);
return buf;
}
......@@ -30,9 +30,9 @@
#[abi = "cdecl"]
pub extern mod rustrt {
#[legacy_exports];
fn vec_reserve_shared_actual(++t: *sys::TypeDesc,
++v: **vec::raw::VecRepr,
++n: libc::size_t);
unsafe fn vec_reserve_shared_actual(++t: *sys::TypeDesc,
++v: **vec::raw::VecRepr,
++n: libc::size_t);
}
#[abi = "rust-intrinsic"]
......
......@@ -160,6 +160,6 @@ pub unsafe fn annihilate() {
extern mod rustrt {
#[legacy_exports];
#[rust_stack]
/*priv*/ fn rust_get_task() -> *c_void;
/*priv*/ unsafe fn rust_get_task() -> *c_void;
}
......@@ -26,73 +26,74 @@
// Alpabetically sorted by link_name
pure fn acos(n: c_double) -> c_double;
pure fn asin(n: c_double) -> c_double;
pure fn atan(n: c_double) -> c_double;
pure fn atan2(a: c_double, b: c_double) -> c_double;
pure fn cbrt(n: c_double) -> c_double;
pure fn ceil(n: c_double) -> c_double;
pure fn copysign(x: c_double, y: c_double) -> c_double;
pure fn cos(n: c_double) -> c_double;
pure fn cosh(n: c_double) -> c_double;
pure fn erf(n: c_double) -> c_double;
pure fn erfc(n: c_double) -> c_double;
pure fn exp(n: c_double) -> c_double;
pure fn expm1(n: c_double) -> c_double;
pure fn exp2(n: c_double) -> c_double;
#[link_name="fabs"] pure fn abs(n: c_double) -> c_double;
unsafe fn acos(n: c_double) -> c_double;
unsafe fn asin(n: c_double) -> c_double;
unsafe fn atan(n: c_double) -> c_double;
unsafe fn atan2(a: c_double, b: c_double) -> c_double;
unsafe fn cbrt(n: c_double) -> c_double;
unsafe fn ceil(n: c_double) -> c_double;
unsafe fn copysign(x: c_double, y: c_double) -> c_double;
unsafe fn cos(n: c_double) -> c_double;
unsafe fn cosh(n: c_double) -> c_double;
unsafe fn erf(n: c_double) -> c_double;
unsafe fn erfc(n: c_double) -> c_double;
unsafe fn exp(n: c_double) -> c_double;
unsafe fn expm1(n: c_double) -> c_double;
unsafe fn exp2(n: c_double) -> c_double;
#[link_name="fabs"] unsafe fn abs(n: c_double) -> c_double;
// rename: for clarity and consistency with add/sub/mul/div
#[link_name="fdim"] pure fn abs_sub(a: c_double, b: c_double) -> c_double;
pure fn floor(n: c_double) -> c_double;
#[link_name="fdim"]
unsafe fn abs_sub(a: c_double, b: c_double) -> c_double;
unsafe fn floor(n: c_double) -> c_double;
// rename: for clarity and consistency with add/sub/mul/div
#[link_name="fma"] pure fn mul_add(a: c_double, b: c_double,
#[link_name="fma"] unsafe fn mul_add(a: c_double, b: c_double,
c: c_double) -> c_double;
#[link_name="fmax"] pure fn fmax(a: c_double, b: c_double) -> c_double;
#[link_name="fmin"] pure fn fmin(a: c_double, b: c_double) -> c_double;
pure fn nextafter(x: c_double, y: c_double) -> c_double;
pure fn frexp(n: c_double, value: &mut c_int) -> c_double;
pure fn hypot(x: c_double, y: c_double) -> c_double;
pure fn ldexp(x: c_double, n: c_int) -> c_double;
#[link_name="fmax"] unsafe fn fmax(a: c_double, b: c_double) -> c_double;
#[link_name="fmin"] unsafe fn fmin(a: c_double, b: c_double) -> c_double;
unsafe fn nextafter(x: c_double, y: c_double) -> c_double;
unsafe fn frexp(n: c_double, value: &mut c_int) -> c_double;
unsafe fn hypot(x: c_double, y: c_double) -> c_double;
unsafe fn ldexp(x: c_double, n: c_int) -> c_double;
#[cfg(unix)]
#[link_name="lgamma_r"] pure fn lgamma(n: c_double,
#[link_name="lgamma_r"] unsafe fn lgamma(n: c_double,
sign: &mut c_int) -> c_double;
#[cfg(windows)]
#[link_name="__lgamma_r"] pure fn lgamma(n: c_double,
#[link_name="__lgamma_r"] unsafe fn lgamma(n: c_double,
sign: &mut c_int) -> c_double;
// renamed: log is a reserved keyword; ln seems more natural, too
#[link_name="log"] pure fn ln(n: c_double) -> c_double;
#[link_name="log"] unsafe fn ln(n: c_double) -> c_double;
// renamed: "logb" /often/ is confused for log2 by beginners
#[link_name="logb"] pure fn log_radix(n: c_double) -> c_double;
#[link_name="logb"] unsafe fn log_radix(n: c_double) -> c_double;
// renamed: to be consitent with log as ln
#[link_name="log1p"] pure fn ln1p(n: c_double) -> c_double;
pure fn log10(n: c_double) -> c_double;
pure fn log2(n: c_double) -> c_double;
#[link_name="ilogb"] pure fn ilog_radix(n: c_double) -> c_int;
pure fn modf(n: c_double, iptr: &mut c_double) -> c_double;
pure fn pow(n: c_double, e: c_double) -> c_double;
#[link_name="log1p"] unsafe fn ln1p(n: c_double) -> c_double;
unsafe fn log10(n: c_double) -> c_double;
unsafe fn log2(n: c_double) -> c_double;
#[link_name="ilogb"] unsafe fn ilog_radix(n: c_double) -> c_int;
unsafe fn modf(n: c_double, iptr: &mut c_double) -> c_double;
unsafe fn pow(n: c_double, e: c_double) -> c_double;
// FIXME (#1379): enable when rounding modes become available
// pure fn rint(n: c_double) -> c_double;
pure fn round(n: c_double) -> c_double;
// unsafe fn rint(n: c_double) -> c_double;
unsafe fn round(n: c_double) -> c_double;
// rename: for consistency with logradix
#[link_name="scalbn"] pure fn ldexp_radix(n: c_double, i: c_int) ->
#[link_name="scalbn"] unsafe fn ldexp_radix(n: c_double, i: c_int) ->
c_double;
pure fn sin(n: c_double) -> c_double;
pure fn sinh(n: c_double) -> c_double;
pure fn sqrt(n: c_double) -> c_double;
pure fn tan(n: c_double) -> c_double;
pure fn tanh(n: c_double) -> c_double;
pure fn tgamma(n: c_double) -> c_double;
pure fn trunc(n: c_double) -> c_double;
unsafe fn sin(n: c_double) -> c_double;
unsafe fn sinh(n: c_double) -> c_double;
unsafe fn sqrt(n: c_double) -> c_double;
unsafe fn tan(n: c_double) -> c_double;
unsafe fn tanh(n: c_double) -> c_double;
unsafe fn tgamma(n: c_double) -> c_double;
unsafe fn trunc(n: c_double) -> c_double;
// These are commonly only available for doubles
pure fn j0(n: c_double) -> c_double;
pure fn j1(n: c_double) -> c_double;
pure fn jn(i: c_int, n: c_double) -> c_double;
unsafe fn j0(n: c_double) -> c_double;
unsafe fn j1(n: c_double) -> c_double;
unsafe fn jn(i: c_int, n: c_double) -> c_double;
pure fn y0(n: c_double) -> c_double;
pure fn y1(n: c_double) -> c_double;
pure fn yn(i: c_int, n: c_double) -> c_double;
unsafe fn y0(n: c_double) -> c_double;
unsafe fn y1(n: c_double) -> c_double;
unsafe fn yn(i: c_int, n: c_double) -> c_double;
}
#[link_name = "m"]
......@@ -101,64 +102,64 @@
// Alpabetically sorted by link_name
#[link_name="acosf"] pure fn acos(n: c_float) -> c_float;
#[link_name="asinf"] pure fn asin(n: c_float) -> c_float;
#[link_name="atanf"] pure fn atan(n: c_float) -> c_float;
#[link_name="atan2f"] pure fn atan2(a: c_float, b: c_float) -> c_float;
#[link_name="cbrtf"] pure fn cbrt(n: c_float) -> c_float;
#[link_name="ceilf"] pure fn ceil(n: c_float) -> c_float;
#[link_name="copysignf"] pure fn copysign(x: c_float,
#[link_name="acosf"] unsafe fn acos(n: c_float) -> c_float;
#[link_name="asinf"] unsafe fn asin(n: c_float) -> c_float;
#[link_name="atanf"] unsafe fn atan(n: c_float) -> c_float;
#[link_name="atan2f"] unsafe fn atan2(a: c_float, b: c_float) -> c_float;
#[link_name="cbrtf"] unsafe fn cbrt(n: c_float) -> c_float;
#[link_name="ceilf"] unsafe fn ceil(n: c_float) -> c_float;
#[link_name="copysignf"] unsafe fn copysign(x: c_float,
y: c_float) -> c_float;
#[link_name="cosf"] pure fn cos(n: c_float) -> c_float;
#[link_name="coshf"] pure fn cosh(n: c_float) -> c_float;
#[link_name="erff"] pure fn erf(n: c_float) -> c_float;
#[link_name="erfcf"] pure fn erfc(n: c_float) -> c_float;
#[link_name="expf"] pure fn exp(n: c_float) -> c_float;
#[link_name="expm1f"]pure fn expm1(n: c_float) -> c_float;
#[link_name="exp2f"] pure fn exp2(n: c_float) -> c_float;
#[link_name="fabsf"] pure fn abs(n: c_float) -> c_float;
#[link_name="fdimf"] pure fn abs_sub(a: c_float, b: c_float) -> c_float;
#[link_name="floorf"] pure fn floor(n: c_float) -> c_float;
#[link_name="frexpf"] pure fn frexp(n: c_float,
#[link_name="cosf"] unsafe fn cos(n: c_float) -> c_float;
#[link_name="coshf"] unsafe fn cosh(n: c_float) -> c_float;
#[link_name="erff"] unsafe fn erf(n: c_float) -> c_float;
#[link_name="erfcf"] unsafe fn erfc(n: c_float) -> c_float;
#[link_name="expf"] unsafe fn exp(n: c_float) -> c_float;
#[link_name="expm1f"]unsafe fn expm1(n: c_float) -> c_float;
#[link_name="exp2f"] unsafe fn exp2(n: c_float) -> c_float;
#[link_name="fabsf"] unsafe fn abs(n: c_float) -> c_float;
#[link_name="fdimf"] unsafe fn abs_sub(a: c_float, b: c_float) -> c_float;
#[link_name="floorf"] unsafe fn floor(n: c_float) -> c_float;
#[link_name="frexpf"] unsafe fn frexp(n: c_float,
value: &mut c_int) -> c_float;
#[link_name="fmaf"] pure fn mul_add(a: c_float,
#[link_name="fmaf"] unsafe fn mul_add(a: c_float,
b: c_float, c: c_float) -> c_float;
#[link_name="fmaxf"] pure fn fmax(a: c_float, b: c_float) -> c_float;
#[link_name="fminf"] pure fn fmin(a: c_float, b: c_float) -> c_float;
#[link_name="nextafterf"] pure fn nextafter(x: c_float,
#[link_name="fmaxf"] unsafe fn fmax(a: c_float, b: c_float) -> c_float;
#[link_name="fminf"] unsafe fn fmin(a: c_float, b: c_float) -> c_float;
#[link_name="nextafterf"] unsafe fn nextafter(x: c_float,
y: c_float) -> c_float;
#[link_name="hypotf"] pure fn hypot(x: c_float, y: c_float) -> c_float;
#[link_name="ldexpf"] pure fn ldexp(x: c_float, n: c_int) -> c_float;
#[link_name="hypotf"] unsafe fn hypot(x: c_float, y: c_float) -> c_float;
#[link_name="ldexpf"] unsafe fn ldexp(x: c_float, n: c_int) -> c_float;
#[cfg(unix)]
#[link_name="lgammaf_r"] pure fn lgamma(n: c_float,
#[link_name="lgammaf_r"] unsafe fn lgamma(n: c_float,
sign: &mut c_int) -> c_float;
#[cfg(windows)]
#[link_name="__lgammaf_r"] pure fn lgamma(n: c_float,
#[link_name="__lgammaf_r"] unsafe fn lgamma(n: c_float,
sign: &mut c_int) -> c_float;
#[link_name="logf"] pure fn ln(n: c_float) -> c_float;
#[link_name="logbf"] pure fn log_radix(n: c_float) -> c_float;
#[link_name="log1pf"] pure fn ln1p(n: c_float) -> c_float;
#[link_name="log2f"] pure fn log2(n: c_float) -> c_float;
#[link_name="log10f"] pure fn log10(n: c_float) -> c_float;
#[link_name="ilogbf"] pure fn ilog_radix(n: c_float) -> c_int;
#[link_name="modff"] pure fn modf(n: c_float,
#[link_name="logf"] unsafe fn ln(n: c_float) -> c_float;
#[link_name="logbf"] unsafe fn log_radix(n: c_float) -> c_float;
#[link_name="log1pf"] unsafe fn ln1p(n: c_float) -> c_float;
#[link_name="log2f"] unsafe fn log2(n: c_float) -> c_float;
#[link_name="log10f"] unsafe fn log10(n: c_float) -> c_float;
#[link_name="ilogbf"] unsafe fn ilog_radix(n: c_float) -> c_int;
#[link_name="modff"] unsafe fn modf(n: c_float,
iptr: &mut c_float) -> c_float;
#[link_name="powf"] pure fn pow(n: c_float, e: c_float) -> c_float;
#[link_name="powf"] unsafe fn pow(n: c_float, e: c_float) -> c_float;
// FIXME (#1379): enable when rounding modes become available
// #[link_name="rintf"] pure fn rint(n: c_float) -> c_float;
#[link_name="roundf"] pure fn round(n: c_float) -> c_float;
#[link_name="scalbnf"] pure fn ldexp_radix(n: c_float, i: c_int)
// #[link_name="rintf"] unsafe fn rint(n: c_float) -> c_float;
#[link_name="roundf"] unsafe fn round(n: c_float) -> c_float;
#[link_name="scalbnf"] unsafe fn ldexp_radix(n: c_float, i: c_int)
-> c_float;
#[link_name="sinf"] pure fn sin(n: c_float) -> c_float;
#[link_name="sinhf"] pure fn sinh(n: c_float) -> c_float;
#[link_name="sqrtf"] pure fn sqrt(n: c_float) -> c_float;
#[link_name="tanf"] pure fn tan(n: c_float) -> c_float;
#[link_name="tanhf"] pure fn tanh(n: c_float) -> c_float;
#[link_name="tgammaf"] pure fn tgamma(n: c_float) -> c_float;
#[link_name="truncf"] pure fn trunc(n: c_float) -> c_float;
#[link_name="sinf"] unsafe fn sin(n: c_float) -> c_float;
#[link_name="sinhf"] unsafe fn sinh(n: c_float) -> c_float;
#[link_name="sqrtf"] unsafe fn sqrt(n: c_float) -> c_float;
#[link_name="tanf"] unsafe fn tan(n: c_float) -> c_float;
#[link_name="tanhf"] unsafe fn tanh(n: c_float) -> c_float;
#[link_name="tgammaf"] unsafe fn tgamma(n: c_float) -> c_float;
#[link_name="truncf"] unsafe fn trunc(n: c_float) -> c_float;
}
// PORT check these by running src/etc/machconsts.c for your architecture
......
......@@ -14,12 +14,88 @@
//! Operations and constants for `f32`
use cmath;
use cmp;
use libc::{c_float, c_int};
use num;
pub use cmath::c_float_utils::*;
pub use cmath::c_float_targ_consts::*;
macro_rules! delegate(
(
fn $name:ident(
$(
$arg:ident : $arg_ty:ty
),*
) -> $rv:ty = $bound_name:path
) => (
pub pure fn $name($( $arg : $arg_ty ),*) -> $rv {
unsafe {
$bound_name($( $arg ),*)
}
}
)
)
delegate!(fn acos(n: c_float) -> c_float = cmath::c_float_utils::acos)
delegate!(fn asin(n: c_float) -> c_float = cmath::c_float_utils::asin)
delegate!(fn atan(n: c_float) -> c_float = cmath::c_float_utils::atan)
delegate!(fn atan2(a: c_float, b: c_float) -> c_float =
cmath::c_float_utils::atan2)
delegate!(fn cbrt(n: c_float) -> c_float = cmath::c_float_utils::cbrt)
delegate!(fn ceil(n: c_float) -> c_float = cmath::c_float_utils::ceil)
delegate!(fn copysign(x: c_float, y: c_float) -> c_float =
cmath::c_float_utils::copysign)
delegate!(fn cos(n: c_float) -> c_float = cmath::c_float_utils::cos)
delegate!(fn cosh(n: c_float) -> c_float = cmath::c_float_utils::cosh)
delegate!(fn erf(n: c_float) -> c_float = cmath::c_float_utils::erf)
delegate!(fn erfc(n: c_float) -> c_float = cmath::c_float_utils::erfc)
delegate!(fn exp(n: c_float) -> c_float = cmath::c_float_utils::exp)
delegate!(fn expm1(n: c_float) -> c_float = cmath::c_float_utils::expm1)
delegate!(fn exp2(n: c_float) -> c_float = cmath::c_float_utils::exp2)
delegate!(fn abs(n: c_float) -> c_float = cmath::c_float_utils::abs)
delegate!(fn abs_sub(a: c_float, b: c_float) -> c_float =
cmath::c_float_utils::abs_sub)
delegate!(fn floor(n: c_float) -> c_float = cmath::c_float_utils::floor)
delegate!(fn mul_add(a: c_float, b: c_float, c: c_float) -> c_float =
cmath::c_float_utils::mul_add)
delegate!(fn fmax(a: c_float, b: c_float) -> c_float =
cmath::c_float_utils::fmax)
delegate!(fn fmin(a: c_float, b: c_float) -> c_float =
cmath::c_float_utils::fmin)
delegate!(fn nextafter(x: c_float, y: c_float) -> c_float =
cmath::c_float_utils::nextafter)
delegate!(fn frexp(n: c_float, value: &mut c_int) -> c_float =
cmath::c_float_utils::frexp)
delegate!(fn hypot(x: c_float, y: c_float) -> c_float =
cmath::c_float_utils::hypot)
delegate!(fn ldexp(x: c_float, n: c_int) -> c_float =
cmath::c_float_utils::ldexp)
delegate!(fn lgamma(n: c_float, sign: &mut c_int) -> c_float =
cmath::c_float_utils::lgamma)
delegate!(fn ln(n: c_float) -> c_float = cmath::c_float_utils::ln)
delegate!(fn log_radix(n: c_float) -> c_float =
cmath::c_float_utils::log_radix)
delegate!(fn ln1p(n: c_float) -> c_float = cmath::c_float_utils::ln1p)
delegate!(fn log10(n: c_float) -> c_float = cmath::c_float_utils::log10)
delegate!(fn log2(n: c_float) -> c_float = cmath::c_float_utils::log2)
delegate!(fn ilog_radix(n: c_float) -> c_int =
cmath::c_float_utils::ilog_radix)
delegate!(fn modf(n: c_float, iptr: &mut c_float) -> c_float =
cmath::c_float_utils::modf)
delegate!(fn pow(n: c_float, e: c_float) -> c_float =
cmath::c_float_utils::pow)
delegate!(fn round(n: c_float) -> c_float = cmath::c_float_utils::round)
delegate!(fn ldexp_radix(n: c_float, i: c_int) -> c_float =
cmath::c_float_utils::ldexp_radix)
delegate!(fn sin(n: c_float) -> c_float = cmath::c_float_utils::sin)
delegate!(fn sinh(n: c_float) -> c_float = cmath::c_float_utils::sinh)
delegate!(fn sqrt(n: c_float) -> c_float = cmath::c_float_utils::sqrt)
delegate!(fn tan(n: c_float) -> c_float = cmath::c_float_utils::tan)
delegate!(fn tanh(n: c_float) -> c_float = cmath::c_float_utils::tanh)
delegate!(fn tgamma(n: c_float) -> c_float = cmath::c_float_utils::tgamma)
delegate!(fn trunc(n: c_float) -> c_float = cmath::c_float_utils::trunc)
// These are not defined inside consts:: for consistency with
// the integer types
......
......@@ -16,12 +16,95 @@
use cmath;
use cmp;
use libc::{c_double, c_int};
use libc;
use num;
pub use cmath::c_double_utils::*;
pub use cmath::c_double_targ_consts::*;
macro_rules! delegate(
(
fn $name:ident(
$(
$arg:ident : $arg_ty:ty
),*
) -> $rv:ty = $bound_name:path
) => (
pub pure fn $name($( $arg : $arg_ty ),*) -> $rv {
unsafe {
$bound_name($( $arg ),*)
}
}
)
)
delegate!(fn acos(n: c_double) -> c_double = cmath::c_double_utils::acos)
delegate!(fn asin(n: c_double) -> c_double = cmath::c_double_utils::asin)
delegate!(fn atan(n: c_double) -> c_double = cmath::c_double_utils::atan)
delegate!(fn atan2(a: c_double, b: c_double) -> c_double =
cmath::c_double_utils::atan2)
delegate!(fn cbrt(n: c_double) -> c_double = cmath::c_double_utils::cbrt)
delegate!(fn ceil(n: c_double) -> c_double = cmath::c_double_utils::ceil)
delegate!(fn copysign(x: c_double, y: c_double) -> c_double =
cmath::c_double_utils::copysign)
delegate!(fn cos(n: c_double) -> c_double = cmath::c_double_utils::cos)
delegate!(fn cosh(n: c_double) -> c_double = cmath::c_double_utils::cosh)
delegate!(fn erf(n: c_double) -> c_double = cmath::c_double_utils::erf)
delegate!(fn erfc(n: c_double) -> c_double = cmath::c_double_utils::erfc)
delegate!(fn exp(n: c_double) -> c_double = cmath::c_double_utils::exp)
delegate!(fn expm1(n: c_double) -> c_double = cmath::c_double_utils::expm1)
delegate!(fn exp2(n: c_double) -> c_double = cmath::c_double_utils::exp2)
delegate!(fn abs(n: c_double) -> c_double = cmath::c_double_utils::abs)
delegate!(fn abs_sub(a: c_double, b: c_double) -> c_double =
cmath::c_double_utils::abs_sub)
delegate!(fn floor(n: c_double) -> c_double = cmath::c_double_utils::floor)
delegate!(fn mul_add(a: c_double, b: c_double, c: c_double) -> c_double =
cmath::c_double_utils::mul_add)
delegate!(fn fmax(a: c_double, b: c_double) -> c_double =
cmath::c_double_utils::fmax)
delegate!(fn fmin(a: c_double, b: c_double) -> c_double =
cmath::c_double_utils::fmin)
delegate!(fn nextafter(x: c_double, y: c_double) -> c_double =
cmath::c_double_utils::nextafter)
delegate!(fn frexp(n: c_double, value: &mut c_int) -> c_double =
cmath::c_double_utils::frexp)
delegate!(fn hypot(x: c_double, y: c_double) -> c_double =
cmath::c_double_utils::hypot)
delegate!(fn ldexp(x: c_double, n: c_int) -> c_double =
cmath::c_double_utils::ldexp)
delegate!(fn lgamma(n: c_double, sign: &mut c_int) -> c_double =
cmath::c_double_utils::lgamma)
delegate!(fn ln(n: c_double) -> c_double = cmath::c_double_utils::ln)
delegate!(fn log_radix(n: c_double) -> c_double =
cmath::c_double_utils::log_radix)
delegate!(fn ln1p(n: c_double) -> c_double = cmath::c_double_utils::ln1p)
delegate!(fn log10(n: c_double) -> c_double = cmath::c_double_utils::log10)
delegate!(fn log2(n: c_double) -> c_double = cmath::c_double_utils::log2)
delegate!(fn ilog_radix(n: c_double) -> c_int =
cmath::c_double_utils::ilog_radix)
delegate!(fn modf(n: c_double, iptr: &mut c_double) -> c_double =
cmath::c_double_utils::modf)
delegate!(fn pow(n: c_double, e: c_double) -> c_double =
cmath::c_double_utils::pow)
delegate!(fn round(n: c_double) -> c_double = cmath::c_double_utils::round)
delegate!(fn ldexp_radix(n: c_double, i: c_int) -> c_double =
cmath::c_double_utils::ldexp_radix)
delegate!(fn sin(n: c_double) -> c_double = cmath::c_double_utils::sin)
delegate!(fn sinh(n: c_double) -> c_double = cmath::c_double_utils::sinh)
delegate!(fn sqrt(n: c_double) -> c_double = cmath::c_double_utils::sqrt)
delegate!(fn tan(n: c_double) -> c_double = cmath::c_double_utils::tan)
delegate!(fn tanh(n: c_double) -> c_double = cmath::c_double_utils::tanh)
delegate!(fn tgamma(n: c_double) -> c_double = cmath::c_double_utils::tgamma)
delegate!(fn trunc(n: c_double) -> c_double = cmath::c_double_utils::trunc)
delegate!(fn j0(n: c_double) -> c_double = cmath::c_double_utils::j0)
delegate!(fn j1(n: c_double) -> c_double = cmath::c_double_utils::j1)
delegate!(fn jn(i: c_int, n: c_double) -> c_double =
cmath::c_double_utils::jn)
delegate!(fn y0(n: c_double) -> c_double = cmath::c_double_utils::y0)
delegate!(fn y1(n: c_double) -> c_double = cmath::c_double_utils::y1)
delegate!(fn yn(i: c_int, n: c_double) -> c_double =
cmath::c_double_utils::yn)
// FIXME (#1433): obtain these in a different way
// These are not defined inside consts:: for consistency with
......@@ -73,10 +156,6 @@
pub pure fn gt(x: f64, y: f64) -> bool { return x > y; }
pub pure fn sqrt(x: f64) -> f64 {
cmath::c_double_utils::sqrt(x as libc::c_double) as f64
}
/// Returns true if `x` is a positive number, including +0.0f640 and +Infinity
pub pure fn is_positive(x: f64) -> bool
{ return x > 0.0f64 || (1.0f64/x) == infinity; }
......
......@@ -25,15 +25,15 @@
use vec;
extern mod rustrt {
fn tdefl_compress_mem_to_heap(psrc_buf: *const c_void,
src_buf_len: size_t,
pout_len: *size_t,
flags: c_int) -> *c_void;
unsafe fn tdefl_compress_mem_to_heap(psrc_buf: *const c_void,
src_buf_len: size_t,
pout_len: *size_t,
flags: c_int) -> *c_void;
fn tinfl_decompress_mem_to_heap(psrc_buf: *const c_void,
src_buf_len: size_t,
pout_len: *size_t,
flags: c_int) -> *c_void;
unsafe fn tinfl_decompress_mem_to_heap(psrc_buf: *const c_void,
src_buf_len: size_t,
pout_len: *size_t,
flags: c_int) -> *c_void;
}
const lz_none : c_int = 0x0; // Huffman-coding only.
......
......@@ -409,12 +409,24 @@ pub fn test_to_str_exact_do_decimal() {
pub pure fn is_finite(x: float) -> bool { f64::is_finite(x as f64) }
pub pure fn is_NaN(x: float) -> bool { f64::is_NaN(x as f64) }
pub pure fn abs(x: float) -> float { f64::abs(x as f64) as float }
pub pure fn sqrt(x: float) -> float { f64::sqrt(x as f64) as float }
pub pure fn atan(x: float) -> float { f64::atan(x as f64) as float }
pub pure fn sin(x: float) -> float { f64::sin(x as f64) as float }
pub pure fn cos(x: float) -> float { f64::cos(x as f64) as float }
pub pure fn tan(x: float) -> float { f64::tan(x as f64) as float }
pub pure fn abs(x: float) -> float {
unsafe { f64::abs(x as f64) as float }
}
pub pure fn sqrt(x: float) -> float {
unsafe { f64::sqrt(x as f64) as float }
}
pub pure fn atan(x: float) -> float {
unsafe { f64::atan(x as f64) as float }
}
pub pure fn sin(x: float) -> float {
unsafe { f64::sin(x as f64) as float }
}
pub pure fn cos(x: float) -> float {
unsafe { f64::cos(x as f64) as float }
}
pub pure fn tan(x: float) -> float {
unsafe { f64::tan(x as f64) as float }
}
#[cfg(notest)]
impl float : Eq {
......
......@@ -61,12 +61,14 @@ struct StackSegment {
extern mod rustrt {
#[legacy_exports];
#[rust_stack]
fn rust_call_tydesc_glue(root: *Word, tydesc: *Word, field: size_t);
unsafe fn rust_call_tydesc_glue(root: *Word,
tydesc: *Word,
field: size_t);
#[rust_stack]
fn rust_gc_metadata() -> *Word;
unsafe fn rust_gc_metadata() -> *Word;
fn rust_get_stack_segment() -> *StackSegment;
unsafe fn rust_get_stack_segment() -> *StackSegment;
}
unsafe fn bump<T, U>(ptr: *T, count: uint) -> *U {
......
......@@ -40,9 +40,9 @@
#[abi = "cdecl"]
extern mod rustrt {
fn rust_get_stdin() -> *libc::FILE;
fn rust_get_stdout() -> *libc::FILE;
fn rust_get_stderr() -> *libc::FILE;
unsafe fn rust_get_stdin() -> *libc::FILE;
unsafe fn rust_get_stdout() -> *libc::FILE;
unsafe fn rust_get_stderr() -> *libc::FILE;
}
// Reading
......@@ -420,22 +420,39 @@ fn convert_whence(whence: SeekStyle) -> i32 {
impl *libc::FILE: Reader {
fn read(&self, bytes: &[mut u8], len: uint) -> uint {
do vec::as_mut_buf(bytes) |buf_p, buf_len| {
assert buf_len >= len;
unsafe {
do vec::as_mut_buf(bytes) |buf_p, buf_len| {
assert buf_len >= len;
let count = libc::fread(buf_p as *mut c_void, 1u as size_t,
len as size_t, *self);
let count = libc::fread(buf_p as *mut c_void, 1u as size_t,
len as size_t, *self);
count as uint
count as uint
}
}
}
fn read_byte(&self) -> int {
unsafe {
libc::fgetc(*self) as int
}
}
fn eof(&self) -> bool {
unsafe {
return libc::feof(*self) != 0 as c_int;
}
}
fn read_byte(&self) -> int { return libc::fgetc(*self) as int; }
fn eof(&self) -> bool { return libc::feof(*self) != 0 as c_int; }
fn seek(&self, offset: int, whence: SeekStyle) {
assert libc::fseek(*self, offset as c_long, convert_whence(whence))
== 0 as c_int;
unsafe {
assert libc::fseek(*self,
offset as c_long,
convert_whence(whence)) == 0 as c_int;
}
}
fn tell(&self) -> uint {
unsafe {
return libc::ftell(*self) as uint;
}
}
fn tell(&self) -> uint { return libc::ftell(*self) as uint; }
}
// A forwarding impl of reader that also holds on to a resource for the
......@@ -455,7 +472,11 @@ fn tell(&self) -> uint { self.base.tell() }
pub struct FILERes {
f: *libc::FILE,
drop { libc::fclose(self.f); }
drop {
unsafe {
libc::fclose(self.f);
}
}
}
pub fn FILERes(f: *libc::FILE) -> FILERes {
......@@ -476,18 +497,24 @@ pub fn FILE_reader(f: *libc::FILE, cleanup: bool) -> Reader {
// top-level functions that take a reader, or a set of default methods on
// reader (which can then be called reader)
pub fn stdin() -> Reader { rustrt::rust_get_stdin() as Reader }
pub fn stdin() -> Reader {
unsafe {
rustrt::rust_get_stdin() as Reader
}
}
pub fn file_reader(path: &Path) -> Result<Reader, ~str> {
let f = os::as_c_charp(path.to_str(), |pathbuf| {
os::as_c_charp("r", |modebuf|
libc::fopen(pathbuf, modebuf)
)
});
return if f as uint == 0u { result::Err(~"error opening "
+ path.to_str()) }
else {
result::Ok(FILE_reader(f, true))
unsafe {
let f = os::as_c_charp(path.to_str(), |pathbuf| {
os::as_c_charp("r", |modebuf|
libc::fopen(pathbuf, modebuf)
)
});
return if f as uint == 0u { result::Err(~"error opening "
+ path.to_str()) }
else {
result::Ok(FILE_reader(f, true))
}
}
}
......@@ -570,25 +597,43 @@ fn get_type(&self) -> WriterType { File }
impl *libc::FILE: Writer {
fn write(&self, v: &[const u8]) {
do vec::as_const_buf(v) |vbuf, len| {
let nout = libc::fwrite(vbuf as *c_void, 1, len as size_t, *self);
if nout != len as size_t {
error!("error writing buffer");
log(error, os::last_os_error());
fail;
unsafe {
do vec::as_const_buf(v) |vbuf, len| {
let nout = libc::fwrite(vbuf as *c_void,
1,
len as size_t,
*self);
if nout != len as size_t {
error!("error writing buffer");
log(error, os::last_os_error());
fail;
}
}
}
}
fn seek(&self, offset: int, whence: SeekStyle) {
assert libc::fseek(*self, offset as c_long, convert_whence(whence))
== 0 as c_int;
unsafe {
assert libc::fseek(*self,
offset as c_long,
convert_whence(whence)) == 0 as c_int;
}
}
fn tell(&self) -> uint {
unsafe {
libc::ftell(*self) as uint
}
}
fn flush(&self) -> int {
unsafe {
libc::fflush(*self) as int
}
}
fn tell(&self) -> uint { libc::ftell(*self) as uint }
fn flush(&self) -> int { libc::fflush(*self) as int }
fn get_type(&self) -> WriterType {
let fd = libc::fileno(*self);
if libc::isatty(fd) == 0 { File }
else { Screen }
unsafe {
let fd = libc::fileno(*self);
if libc::isatty(fd) == 0 { File }
else { Screen }
}
}
}
......@@ -602,17 +647,19 @@ pub fn FILE_writer(f: *libc::FILE, cleanup: bool) -> Writer {
impl fd_t: Writer {
fn write(&self, v: &[const u8]) {
let mut count = 0u;
do vec::as_const_buf(v) |vbuf, len| {
while count < len {
let vb = ptr::const_offset(vbuf, count) as *c_void;
let nout = libc::write(*self, vb, len as size_t);
if nout < 0 as ssize_t {
error!("error writing buffer");
log(error, os::last_os_error());
fail;
unsafe {
let mut count = 0u;
do vec::as_const_buf(v) |vbuf, len| {
while count < len {
let vb = ptr::const_offset(vbuf, count) as *c_void;
let nout = libc::write(*self, vb, len as size_t);
if nout < 0 as ssize_t {
error!("error writing buffer");
log(error, os::last_os_error());
fail;
}
count += nout as uint;
}
count += nout as uint;
}
}
}
......@@ -626,13 +673,19 @@ fn tell(&self) -> uint {
}
fn flush(&self) -> int { 0 }
fn get_type(&self) -> WriterType {
if libc::isatty(*self) == 0 { File } else { Screen }
unsafe {
if libc::isatty(*self) == 0 { File } else { Screen }
}
}
}
pub struct FdRes {
fd: fd_t,
drop { libc::close(self.fd); }
drop {
unsafe {
libc::close(self.fd);
}
}
}
pub fn FdRes(fd: fd_t) -> FdRes {
......@@ -668,9 +721,11 @@ fn wb() -> c_int { O_WRONLY as c_int }
NoFlag => ()
}
}
let fd = do os::as_c_charp(path.to_str()) |pathbuf| {
libc::open(pathbuf, fflags,
(S_IRUSR | S_IWUSR) as c_int)
let fd = unsafe {
do os::as_c_charp(path.to_str()) |pathbuf| {
libc::open(pathbuf, fflags,
(S_IRUSR | S_IWUSR) as c_int)
}
};
if fd < (0 as c_int) {
result::Err(fmt!("error opening %s: %s", path.to_str(),
......@@ -913,14 +968,16 @@ pub fn file_writer(path: &Path, flags: &[FileFlag]) -> Result<Writer, ~str> {
// FIXME: fileflags // #2004
pub fn buffered_file_writer(path: &Path) -> Result<Writer, ~str> {
let f = do os::as_c_charp(path.to_str()) |pathbuf| {
do os::as_c_charp("w") |modebuf| {
libc::fopen(pathbuf, modebuf)
}
};
return if f as uint == 0u { result::Err(~"error opening "
+ path.to_str()) }
else { result::Ok(FILE_writer(f, true)) }
unsafe {
let f = do os::as_c_charp(path.to_str()) |pathbuf| {
do os::as_c_charp("w") |modebuf| {
libc::fopen(pathbuf, modebuf)
}
};
return if f as uint == 0u { result::Err(~"error opening "
+ path.to_str()) }
else { result::Ok(FILE_writer(f, true)) }
}
}
// FIXME (#2004) it would be great if this could be a const
......@@ -1081,12 +1138,16 @@ pub fn Res<t: Copy>(arg: Arg<t>) -> Res<t>{
// outer res
pub fn FILE_res_sync(file: &FILERes, opt_level: Option<Level>,
blk: fn(v: Res<*libc::FILE>)) {
blk(move Res({
val: file.f, opt_level: opt_level,
fsync_fn: fn@(file: *libc::FILE, l: Level) -> int {
return os::fsync_fd(libc::fileno(file), l) as int;
}
}));
unsafe {
blk(move Res({
val: file.f, opt_level: opt_level,
fsync_fn: fn@(file: *libc::FILE, l: Level) -> int {
unsafe {
return os::fsync_fd(libc::fileno(file), l) as int;
}
}
}));
}
}
// fsync fd after executing blk
......
此差异已折叠。
......@@ -22,14 +22,18 @@
#[nolink]
extern mod rustrt {
fn rust_log_console_on();
fn rust_log_console_off();
fn rust_log_str(level: u32, string: *libc::c_char, size: libc::size_t);
unsafe fn rust_log_console_on();
unsafe fn rust_log_console_off();
unsafe fn rust_log_str(level: u32,
string: *libc::c_char,
size: libc::size_t);
}
/// Turns on logging to stdout globally
pub fn console_on() {
rustrt::rust_log_console_on();
unsafe {
rustrt::rust_log_console_on();
}
}
/**
......@@ -40,7 +44,9 @@ pub fn console_on() {
* the RUST_LOG environment variable
*/
pub fn console_off() {
rustrt::rust_log_console_off();
unsafe {
rustrt::rust_log_console_off();
}
}
#[cfg(notest)]
......
......@@ -90,7 +90,9 @@ pub enum Chan<T: Owned> {
/// Constructs a port
pub fn Port<T: Owned>() -> Port<T> {
Port_(@PortPtr(rustrt::new_port(sys::size_of::<T>() as size_t)))
unsafe {
Port_(@PortPtr(rustrt::new_port(sys::size_of::<T>() as size_t)))
}
}
impl<T: Owned> Port<T> {
......@@ -159,11 +161,13 @@ fn as_raw_port<T: Owned, U>(ch: Chan<T>, f: fn(*rust_port) -> U) -> U {
struct PortRef {
p: *rust_port,
drop {
if !ptr::is_null(self.p) {
rustrt::rust_port_drop(self.p);
}
}
drop {
unsafe {
if !ptr::is_null(self.p) {
rustrt::rust_port_drop(self.p);
}
}
}
}
fn PortRef(p: *rust_port) -> PortRef {
......@@ -172,15 +176,17 @@ fn PortRef(p: *rust_port) -> PortRef {
}
}
let p = PortRef(rustrt::rust_port_take(*ch));
unsafe {
let p = PortRef(rustrt::rust_port_take(*ch));
if ptr::is_null(p.p) {
fail ~"unable to locate port for channel"
} else if rustrt::get_task_id() != rustrt::rust_port_task(p.p) {
fail ~"unable to access unowned port"
}
if ptr::is_null(p.p) {
fail ~"unable to locate port for channel"
} else if rustrt::get_task_id() != rustrt::rust_port_task(p.p) {
fail ~"unable to access unowned port"
}
f(p.p)
f(p.p)
}
}
/**
......@@ -188,7 +194,9 @@ fn PortRef(p: *rust_port) -> PortRef {
* construct it.
*/
pub fn Chan<T: Owned>(p: &Port<T>) -> Chan<T> {
Chan_(rustrt::get_port_id((**p).po))
unsafe {
Chan_(rustrt::get_port_id((**p).po))
}
}
/**
......@@ -196,14 +204,16 @@ pub fn Chan<T: Owned>(p: &Port<T>) -> Chan<T> {
* whereupon the caller loses access to it.
*/
pub fn send<T: Owned>(ch: Chan<T>, data: T) {
let Chan_(p) = ch;
let data_ptr = ptr::addr_of(&data) as *();
let res = rustrt::rust_port_id_send(p, data_ptr);
if res != 0 unsafe {
// Data sent successfully
cast::forget(move data);
unsafe {
let Chan_(p) = ch;
let data_ptr = ptr::addr_of(&data) as *();
let res = rustrt::rust_port_id_send(p, data_ptr);
if res != 0 unsafe {
// Data sent successfully
cast::forget(move data);
}
task::yield();
}
task::yield();
}
/**
......@@ -226,61 +236,67 @@ fn peek_chan<T: Owned>(ch: Chan<T>) -> bool {
/// Receive on a raw port pointer
fn recv_<T: Owned>(p: *rust_port) -> T {
let yield = 0;
let yieldp = ptr::addr_of(&yield);
let mut res;
res = rusti::init::<T>();
rustrt::port_recv(ptr::addr_of(&res) as *uint, p, yieldp);
if yield != 0 {
// Data isn't available yet, so res has not been initialized.
task::yield();
} else {
// In the absence of compiler-generated preemption points
// this is a good place to yield
task::yield();
unsafe {
let yield = 0;
let yieldp = ptr::addr_of(&yield);
let mut res;
res = rusti::init::<T>();
rustrt::port_recv(ptr::addr_of(&res) as *uint, p, yieldp);
if yield != 0 {
// Data isn't available yet, so res has not been initialized.
task::yield();
} else {
// In the absence of compiler-generated preemption points
// this is a good place to yield
task::yield();
}
move res
}
move res
}
fn peek_(p: *rust_port) -> bool {
// Yield here before we check to see if someone sent us a message
// FIXME #524, if the compiler generates yields, we don't need this
task::yield();
rustrt::rust_port_size(p) != 0 as libc::size_t
unsafe {
// Yield here before we check to see if someone sent us a message
// FIXME #524, if the compiler generates yields, we don't need this
task::yield();
rustrt::rust_port_size(p) != 0 as libc::size_t
}
}
/// Receive on one of two ports
pub fn select2<A: Owned, B: Owned>(p_a: Port<A>, p_b: Port<B>)
-> Either<A, B> {
let ports = ~[(**p_a).po, (**p_b).po];
let yield = 0, yieldp = ptr::addr_of(&yield);
let mut resport: *rust_port;
resport = rusti::init::<*rust_port>();
do vec::as_imm_buf(ports) |ports, n_ports| {
rustrt::rust_port_select(ptr::addr_of(&resport), ports,
n_ports as size_t, yieldp);
}
unsafe {
let ports = ~[(**p_a).po, (**p_b).po];
let yield = 0, yieldp = ptr::addr_of(&yield);
let mut resport: *rust_port;
resport = rusti::init::<*rust_port>();
do vec::as_imm_buf(ports) |ports, n_ports| {
rustrt::rust_port_select(ptr::addr_of(&resport), ports,
n_ports as size_t, yieldp);
}
if yield != 0 {
// Wait for data
task::yield();
} else {
// As in recv, this is a good place to yield anyway until
// the compiler generates yield calls
task::yield();
}
if yield != 0 {
// Wait for data
task::yield();
} else {
// As in recv, this is a good place to yield anyway until
// the compiler generates yield calls
task::yield();
}
// Now we know the port we're supposed to receive from
assert resport != ptr::null();
// Now we know the port we're supposed to receive from
assert resport != ptr::null();
if resport == (**p_a).po {
either::Left(recv(p_a))
} else if resport == (**p_b).po {
either::Right(recv(p_b))
} else {
fail ~"unexpected result from rust_port_select";
if resport == (**p_a).po {
either::Left(recv(p_a))
} else if resport == (**p_b).po {
either::Right(recv(p_b))
} else {
fail ~"unexpected result from rust_port_select";
}
}
}
......@@ -295,24 +311,25 @@ enum rust_port {}
#[abi = "cdecl"]
extern mod rustrt {
fn rust_port_id_send(target_port: port_id, data: *()) -> libc::uintptr_t;
unsafe fn rust_port_id_send(target_port: port_id, data: *())
-> libc::uintptr_t;
fn new_port(unit_sz: libc::size_t) -> *rust_port;
fn del_port(po: *rust_port);
fn rust_port_begin_detach(po: *rust_port,
unsafe fn new_port(unit_sz: libc::size_t) -> *rust_port;
unsafe fn del_port(po: *rust_port);
unsafe fn rust_port_begin_detach(po: *rust_port,
yield: *libc::uintptr_t);
fn rust_port_end_detach(po: *rust_port);
fn get_port_id(po: *rust_port) -> port_id;
fn rust_port_size(po: *rust_port) -> libc::size_t;
fn port_recv(dptr: *uint, po: *rust_port,
unsafe fn rust_port_end_detach(po: *rust_port);
unsafe fn get_port_id(po: *rust_port) -> port_id;
unsafe fn rust_port_size(po: *rust_port) -> libc::size_t;
unsafe fn port_recv(dptr: *uint, po: *rust_port,
yield: *libc::uintptr_t);
fn rust_port_select(dptr: **rust_port, ports: **rust_port,
unsafe fn rust_port_select(dptr: **rust_port, ports: **rust_port,
n_ports: libc::size_t,
yield: *libc::uintptr_t);
fn rust_port_take(port_id: port_id) -> *rust_port;
fn rust_port_drop(p: *rust_port);
fn rust_port_task(p: *rust_port) -> libc::uintptr_t;
fn get_task_id() -> libc::uintptr_t;
unsafe fn rust_port_take(port_id: port_id) -> *rust_port;
unsafe fn rust_port_drop(p: *rust_port);
unsafe fn rust_port_task(p: *rust_port) -> libc::uintptr_t;
unsafe fn get_task_id() -> libc::uintptr_t;
}
#[abi = "rust-intrinsic"]
......
此差异已折叠。
......@@ -243,21 +243,25 @@ pub fn default_stat() -> libc::stat {
impl Path {
fn stat(&self) -> Option<libc::stat> {
do str::as_c_str(self.to_str()) |buf| {
let mut st = stat::arch::default_stat();
let r = libc::stat(buf, ptr::mut_addr_of(&st));
unsafe {
do str::as_c_str(self.to_str()) |buf| {
let mut st = stat::arch::default_stat();
let r = libc::stat(buf, ptr::mut_addr_of(&st));
if r == 0 { Some(move st) } else { None }
if r == 0 { Some(move st) } else { None }
}
}
}
#[cfg(unix)]
fn lstat(&self) -> Option<libc::stat> {
do str::as_c_str(self.to_str()) |buf| {
let mut st = stat::arch::default_stat();
let r = libc::lstat(buf, ptr::mut_addr_of(&st));
unsafe {
do str::as_c_str(self.to_str()) |buf| {
let mut st = stat::arch::default_stat();
let r = libc::lstat(buf, ptr::mut_addr_of(&st));
if r == 0 { Some(move st) } else { None }
if r == 0 { Some(move st) } else { None }
}
}
}
......
......@@ -173,7 +173,11 @@ unsafe fn mark_blocked(this: *rust_task) -> State {
unsafe fn unblock() {
let old_task = swap_task(&mut self.blocked_task, ptr::null());
if !old_task.is_null() { rustrt::rust_task_deref(old_task) }
if !old_task.is_null() {
unsafe {
rustrt::rust_task_deref(old_task)
}
}
match swap_state_acq(&mut self.state, Empty) {
Empty | Blocked => (),
Terminated => self.state = Terminated,
......@@ -300,27 +304,30 @@ pub fn swap_task(dst: &mut *rust_task, src: *rust_task) -> *rust_task {
#[doc(hidden)]
extern mod rustrt {
#[rust_stack]
fn rust_get_task() -> *rust_task;
unsafe fn rust_get_task() -> *rust_task;
#[rust_stack]
fn rust_task_ref(task: *rust_task);
fn rust_task_deref(task: *rust_task);
unsafe fn rust_task_ref(task: *rust_task);
unsafe fn rust_task_deref(task: *rust_task);
#[rust_stack]
fn task_clear_event_reject(task: *rust_task);
unsafe fn task_clear_event_reject(task: *rust_task);
fn task_wait_event(this: *rust_task, killed: &mut *libc::c_void) -> bool;
pure fn task_signal_event(target: *rust_task, event: *libc::c_void);
unsafe fn task_wait_event(this: *rust_task, killed: &mut *libc::c_void)
-> bool;
unsafe fn task_signal_event(target: *rust_task, event: *libc::c_void);
}
#[doc(hidden)]
fn wait_event(this: *rust_task) -> *libc::c_void {
let mut event = ptr::null();
unsafe {
let mut event = ptr::null();
let killed = rustrt::task_wait_event(this, &mut event);
if killed && !task::failing() {
fail ~"killed"
let killed = rustrt::task_wait_event(this, &mut event);
if killed && !task::failing() {
fail ~"killed"
}
event
}
event
}
#[doc(hidden)]
......@@ -397,9 +404,12 @@ pub fn send<T: Owned, Tbuffer: Owned>(p: SendPacketBuffered<T, Tbuffer>,
debug!("waking up task for %?", p_);
let old_task = swap_task(&mut p.header.blocked_task, ptr::null());
if !old_task.is_null() {
rustrt::task_signal_event(
old_task, ptr::addr_of(&(p.header)) as *libc::c_void);
rustrt::rust_task_deref(old_task);
unsafe {
rustrt::task_signal_event(
old_task,
ptr::addr_of(&(p.header)) as *libc::c_void);
rustrt::rust_task_deref(old_task);
}
}
// The receiver will eventually clean this up.
......@@ -445,7 +455,9 @@ struct DropState {
let old_task = swap_task(&mut self.p.blocked_task,
ptr::null());
if !old_task.is_null() {
rustrt::rust_task_deref(old_task);
unsafe {
rustrt::rust_task_deref(old_task);
}
}
}
}
......@@ -466,9 +478,11 @@ struct DropState {
}
// regular path
let this = rustrt::rust_get_task();
rustrt::task_clear_event_reject(this);
rustrt::rust_task_ref(this);
let this = unsafe { rustrt::rust_get_task() };
unsafe {
rustrt::task_clear_event_reject(this);
rustrt::rust_task_ref(this);
};
debug!("blocked = %x this = %x", p.header.blocked_task as uint,
this as uint);
let old_task = swap_task(&mut p.header.blocked_task, this);
......@@ -479,7 +493,10 @@ struct DropState {
let mut first = true;
let mut count = SPIN_COUNT;
loop {
rustrt::task_clear_event_reject(this);
unsafe {
rustrt::task_clear_event_reject(this);
}
let old_state = swap_state_acq(&mut p.header.state,
Blocked);
match old_state {
......@@ -507,7 +524,9 @@ struct DropState {
payload <-> p.payload;
let old_task = swap_task(&mut p.header.blocked_task, ptr::null());
if !old_task.is_null() {
rustrt::rust_task_deref(old_task);
unsafe {
rustrt::rust_task_deref(old_task);
}
}
p.header.state = Empty;
return Some(option::unwrap(move payload))
......@@ -519,7 +538,9 @@ struct DropState {
let old_task = swap_task(&mut p.header.blocked_task, ptr::null());
if !old_task.is_null() {
rustrt::rust_task_deref(old_task);
unsafe {
rustrt::rust_task_deref(old_task);
}
}
return None;
}
......@@ -554,10 +575,12 @@ fn sender_terminate<T: Owned>(p: *Packet<T>) {
// wake up the target
let old_task = swap_task(&mut p.header.blocked_task, ptr::null());
if !old_task.is_null() {
rustrt::task_signal_event(
old_task,
ptr::addr_of(&(p.header)) as *libc::c_void);
rustrt::rust_task_deref(old_task);
unsafe {
rustrt::task_signal_event(
old_task,
ptr::addr_of(&(p.header)) as *libc::c_void);
rustrt::rust_task_deref(old_task);
}
}
// The receiver will eventually clean up.
}
......@@ -583,8 +606,10 @@ fn receiver_terminate<T: Owned>(p: *Packet<T>) {
Blocked => {
let old_task = swap_task(&mut p.header.blocked_task, ptr::null());
if !old_task.is_null() {
rustrt::rust_task_deref(old_task);
assert old_task == rustrt::rust_get_task();
unsafe {
rustrt::rust_task_deref(old_task);
assert old_task == rustrt::rust_get_task();
}
}
}
Terminated | Full => {
......@@ -605,9 +630,12 @@ fn receiver_terminate<T: Owned>(p: *Packet<T>) {
*/
fn wait_many<T: Selectable>(pkts: &[T]) -> uint {
let this = rustrt::rust_get_task();
let this = unsafe { rustrt::rust_get_task() };
unsafe {
rustrt::task_clear_event_reject(this);
}
rustrt::task_clear_event_reject(this);
let mut data_avail = false;
let mut ready_packet = pkts.len();
for pkts.eachi |i, p| unsafe {
......
......@@ -30,18 +30,17 @@
extern mod rustrt {
#[legacy_exports];
fn rust_task_weaken(ch: rust_port_id);
fn rust_task_unweaken(ch: rust_port_id);
unsafe fn rust_task_weaken(ch: rust_port_id);
unsafe fn rust_task_unweaken(ch: rust_port_id);
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);
unsafe fn rust_create_little_lock() -> rust_little_lock;
unsafe fn rust_destroy_little_lock(lock: rust_little_lock);
unsafe fn rust_lock_little_lock(lock: rust_little_lock);
unsafe fn rust_unlock_little_lock(lock: rust_little_lock);
}
#[abi = "rust-intrinsic"]
extern mod rusti {
fn atomic_cxchg(dst: &mut int, old: int, src: int) -> int;
fn atomic_xadd(dst: &mut int, src: int) -> int;
fn atomic_xsub(dst: &mut int, src: int) -> int;
......@@ -490,12 +489,18 @@ pub unsafe fn clone_shared_mutable_state<T: Owned>(rc: &SharedMutableState<T>)
struct LittleLock {
l: rust_little_lock,
drop { rustrt::rust_destroy_little_lock(self.l); }
drop {
unsafe {
rustrt::rust_destroy_little_lock(self.l);
}
}
}
fn LittleLock() -> LittleLock {
LittleLock {
l: rustrt::rust_create_little_lock()
unsafe {
LittleLock {
l: rustrt::rust_create_little_lock()
}
}
}
......@@ -504,7 +509,11 @@ impl LittleLock {
unsafe fn lock<T>(f: fn() -> T) -> T {
struct Unlock {
l: rust_little_lock,
drop { rustrt::rust_unlock_little_lock(self.l); }
drop {
unsafe {
rustrt::rust_unlock_little_lock(self.l);
}
}
}
fn Unlock(l: rust_little_lock) -> Unlock {
......
......@@ -26,16 +26,22 @@
#[abi = "cdecl"]
extern mod libc_ {
#[rust_stack]
fn memcpy(dest: *mut c_void, src: *const c_void,
n: libc::size_t) -> *c_void;
unsafe fn memcpy(dest: *mut c_void,
src: *const c_void,
n: libc::size_t)
-> *c_void;
#[rust_stack]
fn memmove(dest: *mut c_void, src: *const c_void,
n: libc::size_t) -> *c_void;
unsafe fn memmove(dest: *mut c_void,
src: *const c_void,
n: libc::size_t)
-> *c_void;
#[rust_stack]
fn memset(dest: *mut c_void, c: libc::c_int,
len: libc::size_t) -> *c_void;
unsafe fn memset(dest: *mut c_void,
c: libc::c_int,
len: libc::size_t)
-> *c_void;
}
#[abi = "rust-intrinsic"]
......
......@@ -28,11 +28,11 @@ enum rctx {}
#[abi = "cdecl"]
extern mod rustrt {
fn rand_seed() -> ~[u8];
fn rand_new() -> *rctx;
fn rand_new_seeded2(&&seed: ~[u8]) -> *rctx;
fn rand_next(c: *rctx) -> u32;
fn rand_free(c: *rctx);
unsafe fn rand_seed() -> ~[u8];
unsafe fn rand_new() -> *rctx;
unsafe fn rand_new_seeded2(&&seed: ~[u8]) -> *rctx;
unsafe fn rand_next(c: *rctx) -> u32;
unsafe fn rand_free(c: *rctx);
}
/// A random number generator
......@@ -265,7 +265,11 @@ fn shuffle_mut<T>(values: &[mut T]) {
struct RandRes {
c: *rctx,
drop { rustrt::rand_free(self.c); }
drop {
unsafe {
rustrt::rand_free(self.c);
}
}
}
fn RandRes(c: *rctx) -> RandRes {
......@@ -275,17 +279,25 @@ fn RandRes(c: *rctx) -> RandRes {
}
impl @RandRes: Rng {
fn next() -> u32 { return rustrt::rand_next((*self).c); }
fn next() -> u32 {
unsafe {
return rustrt::rand_next((*self).c);
}
}
}
/// Create a new random seed for seeded_rng
pub fn seed() -> ~[u8] {
rustrt::rand_seed()
unsafe {
rustrt::rand_seed()
}
}
/// Create a random number generator with a system specified seed
pub fn Rng() -> Rng {
@RandRes(rustrt::rand_new()) as Rng
unsafe {
@RandRes(rustrt::rand_new()) as Rng
}
}
/**
......@@ -295,7 +307,9 @@ pub fn Rng() -> Rng {
* length.
*/
pub fn seeded_rng(seed: &~[u8]) -> Rng {
@RandRes(rustrt::rand_new_seeded2(*seed)) as Rng
unsafe {
@RandRes(rustrt::rand_new_seeded2(*seed)) as Rng
}
}
type XorShiftState = {
......@@ -343,11 +357,11 @@ pub fn task_rng() -> Rng {
}
match r {
None => {
let rng = @RandRes(rustrt::rand_new());
unsafe {
let rng = @RandRes(rustrt::rand_new());
task::local_data::local_data_set(tls_rng_state, rng);
rng as Rng
}
rng as Rng
}
Some(rng) => rng as Rng
}
......
......@@ -26,16 +26,17 @@
extern mod rustrt {
#[rust_stack]
fn rust_upcall_exchange_malloc(td: *c_char, size: uintptr_t) -> *c_char;
unsafe fn rust_upcall_exchange_malloc(td: *c_char, size: uintptr_t)
-> *c_char;
#[rust_stack]
fn rust_upcall_exchange_free(ptr: *c_char);
unsafe fn rust_upcall_exchange_free(ptr: *c_char);
#[rust_stack]
fn rust_upcall_malloc(td: *c_char, size: uintptr_t) -> *c_char;
unsafe fn rust_upcall_malloc(td: *c_char, size: uintptr_t) -> *c_char;
#[rust_stack]
fn rust_upcall_free(ptr: *c_char);
unsafe fn rust_upcall_free(ptr: *c_char);
}
#[rt(fail_)]
......@@ -46,8 +47,8 @@ pub fn rt_fail_(expr: *c_char, file: *c_char, line: size_t) -> ! {
#[rt(fail_bounds_check)]
#[lang="fail_bounds_check"]
pub fn rt_fail_bounds_check(file: *c_char, line: size_t,
index: size_t, len: size_t) {
pub unsafe fn rt_fail_bounds_check(file: *c_char, line: size_t,
index: size_t, len: size_t) {
let msg = fmt!("index out of bounds: the len is %d but the index is %d",
len as int, index as int);
do str::as_buf(msg) |p, _len| {
......@@ -57,7 +58,7 @@ pub fn rt_fail_bounds_check(file: *c_char, line: size_t,
#[rt(exchange_malloc)]
#[lang="exchange_malloc"]
pub fn rt_exchange_malloc(td: *c_char, size: uintptr_t) -> *c_char {
pub unsafe fn rt_exchange_malloc(td: *c_char, size: uintptr_t) -> *c_char {
return rustrt::rust_upcall_exchange_malloc(td, size);
}
......@@ -66,13 +67,13 @@ pub fn rt_exchange_malloc(td: *c_char, size: uintptr_t) -> *c_char {
// problem occurs, call exit instead.
#[rt(exchange_free)]
#[lang="exchange_free"]
pub fn rt_exchange_free(ptr: *c_char) {
pub unsafe fn rt_exchange_free(ptr: *c_char) {
rustrt::rust_upcall_exchange_free(ptr);
}
#[rt(malloc)]
#[lang="malloc"]
pub fn rt_malloc(td: *c_char, size: uintptr_t) -> *c_char {
pub unsafe fn rt_malloc(td: *c_char, size: uintptr_t) -> *c_char {
return rustrt::rust_upcall_malloc(td, size);
}
......@@ -81,7 +82,7 @@ pub fn rt_malloc(td: *c_char, size: uintptr_t) -> *c_char {
// problem occurs, call exit instead.
#[rt(free)]
#[lang="free"]
pub fn rt_free(ptr: *c_char) {
pub unsafe fn rt_free(ptr: *c_char) {
rustrt::rust_upcall_free(ptr);
}
......
......@@ -29,10 +29,10 @@
#[abi = "cdecl"]
extern mod rustrt {
fn rust_run_program(argv: **libc::c_char, envp: *c_void,
dir: *libc::c_char,
in_fd: c_int, out_fd: c_int, err_fd: c_int)
-> pid_t;
unsafe fn rust_run_program(argv: **libc::c_char, envp: *c_void,
dir: *libc::c_char,
in_fd: c_int, out_fd: c_int, err_fd: c_int)
-> pid_t;
}
/// A value representing a child process
......@@ -84,12 +84,14 @@ pub fn spawn_process(prog: &str, args: &[~str],
env: &Option<~[(~str,~str)]>,
dir: &Option<~str>,
in_fd: c_int, out_fd: c_int, err_fd: c_int)
-> pid_t {
do with_argv(prog, args) |argv| {
do with_envp(env) |envp| {
do with_dirp(dir) |dirp| {
rustrt::rust_run_program(argv, envp, dirp,
in_fd, out_fd, err_fd)
-> pid_t {
unsafe {
do with_argv(prog, args) |argv| {
do with_envp(env) |envp| {
do with_dirp(dir) |dirp| {
rustrt::rust_run_program(argv, envp, dirp,
in_fd, out_fd, err_fd)
}
}
}
}
......@@ -202,69 +204,83 @@ pub fn run_program(prog: &str, args: &[~str]) -> int {
* A class with a <program> field
*/
pub fn start_program(prog: &str, args: &[~str]) -> Program {
let pipe_input = os::pipe();
let pipe_output = os::pipe();
let pipe_err = os::pipe();
let pid =
spawn_process(prog, args, &None, &None,
pipe_input.in, pipe_output.out,
pipe_err.out);
unsafe {
let pipe_input = os::pipe();
let pipe_output = os::pipe();
let pipe_err = os::pipe();
let pid =
spawn_process(prog, args, &None, &None,
pipe_input.in, pipe_output.out,
pipe_err.out);
unsafe {
if pid == -1 as pid_t { fail; }
libc::close(pipe_input.in);
libc::close(pipe_output.out);
libc::close(pipe_err.out);
}
if pid == -1 as pid_t { fail; }
libc::close(pipe_input.in);
libc::close(pipe_output.out);
libc::close(pipe_err.out);
type ProgRepr = {pid: pid_t,
mut in_fd: c_int,
out_file: *libc::FILE,
err_file: *libc::FILE,
mut finished: bool};
fn close_repr_input(r: &ProgRepr) {
let invalid_fd = -1i32;
if r.in_fd != invalid_fd {
libc::close(r.in_fd);
r.in_fd = invalid_fd;
type ProgRepr = {pid: pid_t,
mut in_fd: c_int,
out_file: *libc::FILE,
err_file: *libc::FILE,
mut finished: bool};
fn close_repr_input(r: &ProgRepr) {
let invalid_fd = -1i32;
if r.in_fd != invalid_fd {
unsafe {
libc::close(r.in_fd);
}
r.in_fd = invalid_fd;
}
}
fn finish_repr(r: &ProgRepr) -> int {
if r.finished { return 0; }
r.finished = true;
close_repr_input(r);
return waitpid(r.pid);
}
fn destroy_repr(r: &ProgRepr) {
unsafe {
finish_repr(r);
libc::fclose(r.out_file);
libc::fclose(r.err_file);
}
}
struct ProgRes {
r: ProgRepr,
drop { destroy_repr(&self.r); }
}
}
fn finish_repr(r: &ProgRepr) -> int {
if r.finished { return 0; }
r.finished = true;
close_repr_input(r);
return waitpid(r.pid);
}
fn destroy_repr(r: &ProgRepr) {
finish_repr(r);
libc::fclose(r.out_file);
libc::fclose(r.err_file);
}
struct ProgRes {
r: ProgRepr,
drop { destroy_repr(&self.r); }
}
fn ProgRes(r: ProgRepr) -> ProgRes {
ProgRes {
r: move r
fn ProgRes(r: ProgRepr) -> ProgRes {
ProgRes {
r: move r
}
}
}
impl ProgRes: Program {
fn get_id() -> pid_t { return self.r.pid; }
fn input() -> io::Writer { io::fd_writer(self.r.in_fd, false) }
fn output() -> io::Reader { io::FILE_reader(self.r.out_file, false) }
fn err() -> io::Reader { io::FILE_reader(self.r.err_file, false) }
fn close_input() { close_repr_input(&self.r); }
fn finish() -> int { finish_repr(&self.r) }
fn destroy() { destroy_repr(&self.r); }
impl ProgRes: Program {
fn get_id() -> pid_t { return self.r.pid; }
fn input() -> io::Writer {
io::fd_writer(self.r.in_fd, false)
}
fn output() -> io::Reader {
io::FILE_reader(self.r.out_file, false)
}
fn err() -> io::Reader {
io::FILE_reader(self.r.err_file, false)
}
fn close_input() { close_repr_input(&self.r); }
fn finish() -> int { finish_repr(&self.r) }
fn destroy() { destroy_repr(&self.r); }
}
let repr = {pid: pid,
mut in_fd: pipe_input.out,
out_file: os::fdopen(pipe_output.in),
err_file: os::fdopen(pipe_err.in),
mut finished: false};
return ProgRes(move repr) as Program;
}
let repr = {pid: pid,
mut in_fd: pipe_input.out,
out_file: os::fdopen(pipe_output.in),
err_file: os::fdopen(pipe_err.in),
mut finished: false};
return ProgRes(move repr) as Program;
}
fn read_all(rd: io::Reader) -> ~str {
......@@ -294,60 +310,61 @@ fn read_all(rd: io::Reader) -> ~str {
*/
pub fn program_output(prog: &str, args: &[~str]) ->
{status: int, out: ~str, err: ~str} {
unsafe {
let pipe_in = os::pipe();
let pipe_out = os::pipe();
let pipe_err = os::pipe();
let pid = spawn_process(prog, args, &None, &None,
pipe_in.in, pipe_out.out, pipe_err.out);
let pipe_in = os::pipe();
let pipe_out = os::pipe();
let pipe_err = os::pipe();
let pid = spawn_process(prog, args, &None, &None,
pipe_in.in, pipe_out.out, pipe_err.out);
os::close(pipe_in.in);
os::close(pipe_out.out);
os::close(pipe_err.out);
if pid == -1i32 {
os::close(pipe_in.out);
os::close(pipe_out.in);
os::close(pipe_err.in);
fail;
}
os::close(pipe_in.in);
os::close(pipe_out.out);
os::close(pipe_err.out);
if pid == -1i32 {
os::close(pipe_in.out);
os::close(pipe_out.in);
os::close(pipe_err.in);
fail;
}
os::close(pipe_in.out);
// Spawn two entire schedulers to read both stdout and sterr
// in parallel so we don't deadlock while blocking on one
// or the other. FIXME (#2625): Surely there's a much more
// clever way to do this.
let p = oldcomm::Port();
let ch = oldcomm::Chan(&p);
do task::spawn_sched(task::SingleThreaded) {
let errput = readclose(pipe_err.in);
oldcomm::send(ch, (2, move errput));
};
do task::spawn_sched(task::SingleThreaded) {
let output = readclose(pipe_out.in);
oldcomm::send(ch, (1, move output));
};
let status = run::waitpid(pid);
let mut errs = ~"";
let mut outs = ~"";
let mut count = 2;
while count > 0 {
let stream = oldcomm::recv(p);
match stream {
(1, copy s) => {
outs = move s;
}
(2, copy s) => {
errs = move s;
}
(n, _) => {
fail(fmt!("program_output received an unexpected file \
number: %u", n));
}
// Spawn two entire schedulers to read both stdout and sterr
// in parallel so we don't deadlock while blocking on one
// or the other. FIXME (#2625): Surely there's a much more
// clever way to do this.
let p = oldcomm::Port();
let ch = oldcomm::Chan(&p);
do task::spawn_sched(task::SingleThreaded) {
let errput = readclose(pipe_err.in);
oldcomm::send(ch, (2, move errput));
};
count -= 1;
};
return {status: status, out: move outs, err: move errs};
do task::spawn_sched(task::SingleThreaded) {
let output = readclose(pipe_out.in);
oldcomm::send(ch, (1, move output));
};
let status = run::waitpid(pid);
let mut errs = ~"";
let mut outs = ~"";
let mut count = 2;
while count > 0 {
let stream = oldcomm::recv(p);
match stream {
(1, copy s) => {
outs = move s;
}
(2, copy s) => {
errs = move s;
}
(n, _) => {
fail(fmt!("program_output received an unexpected file \
number: %u", n));
}
};
count -= 1;
};
return {status: status, out: move outs, err: move errs};
}
}
pub fn writeclose(fd: c_int, s: ~str) {
......@@ -361,17 +378,19 @@ pub fn writeclose(fd: c_int, s: ~str) {
}
pub fn readclose(fd: c_int) -> ~str {
let file = os::fdopen(fd);
let reader = io::FILE_reader(file, false);
let buf = io::with_bytes_writer(|writer| {
let mut bytes = [mut 0, ..4096];
while !reader.eof() {
let nread = reader.read(bytes, bytes.len());
writer.write(bytes.view(0, nread));
}
});
os::fclose(file);
str::from_bytes(buf)
unsafe {
let file = os::fdopen(fd);
let reader = io::FILE_reader(file, false);
let buf = io::with_bytes_writer(|writer| {
let mut bytes = [mut 0, ..4096];
while !reader.eof() {
let nread = reader.read(bytes, bytes.len());
writer.write(bytes.view(0, nread));
}
});
os::fclose(file);
str::from_bytes(buf)
}
}
/// Waits for a process to exit and returns the exit code
......
......@@ -85,16 +85,20 @@ fn run(i: int) {
}
fn breakpoint() {
rustrt::rust_dbg_breakpoint()
unsafe {
rustrt::rust_dbg_breakpoint()
}
}
fn frame_address(f: fn(++x: *u8)) {
rusti::frame_address(f)
unsafe {
rusti::frame_address(f)
}
}
extern mod rustrt {
#[legacy_exports];
fn rust_dbg_breakpoint();
unsafe fn rust_dbg_breakpoint();
}
#[abi = "rust-intrinsic"]
......
......@@ -53,7 +53,7 @@ pub struct Closure {
extern mod rustrt {
#[rust_stack]
fn rust_upcall_fail(expr: *c_char, file: *c_char, line: size_t);
unsafe fn rust_upcall_fail(expr: *c_char, file: *c_char, line: size_t);
}
/// Compares contents of two pointers using the default method.
......
......@@ -947,12 +947,12 @@ fn test_spawn_sched_childs_on_same_sched() {
#[nolink]
#[cfg(test)]
extern mod testrt {
fn rust_dbg_lock_create() -> *libc::c_void;
fn rust_dbg_lock_destroy(lock: *libc::c_void);
fn rust_dbg_lock_lock(lock: *libc::c_void);
fn rust_dbg_lock_unlock(lock: *libc::c_void);
fn rust_dbg_lock_wait(lock: *libc::c_void);
fn rust_dbg_lock_signal(lock: *libc::c_void);
unsafe fn rust_dbg_lock_create() -> *libc::c_void;
unsafe fn rust_dbg_lock_destroy(lock: *libc::c_void);
unsafe fn rust_dbg_lock_lock(lock: *libc::c_void);
unsafe fn rust_dbg_lock_unlock(lock: *libc::c_void);
unsafe fn rust_dbg_lock_wait(lock: *libc::c_void);
unsafe fn rust_dbg_lock_signal(lock: *libc::c_void);
}
#[test]
......
......@@ -30,9 +30,9 @@
#[abi = "cdecl"]
pub extern mod rustrt {
fn vec_reserve_shared(++t: *sys::TypeDesc,
++v: **raw::VecRepr,
++n: libc::size_t);
unsafe fn vec_reserve_shared(++t: *sys::TypeDesc,
++v: **raw::VecRepr,
++n: libc::size_t);
}
#[abi = "rust-intrinsic"]
......
......@@ -76,10 +76,18 @@ pub fn WriteOutputFile(sess: Session,
Output: *c_char, FileType: c_uint,
OptLevel: c_int,
EnableSegmentedStacks: bool) {
let result = llvm::LLVMRustWriteOutputFile(
PM, M, Triple, Output, FileType, OptLevel, EnableSegmentedStacks);
if (!result) {
llvm_err(sess, ~"Could not write output");
unsafe {
let result = llvm::LLVMRustWriteOutputFile(
PM,
M,
Triple,
Output,
FileType,
OptLevel,
EnableSegmentedStacks);
if (!result) {
llvm_err(sess, ~"Could not write output");
}
}
}
......@@ -190,146 +198,170 @@ fn is_object_or_assembly_or_exe(ot: output_type) -> bool {
}
fn run_passes(sess: Session, llmod: ModuleRef, output: &Path) {
let opts = sess.opts;
if sess.time_llvm_passes() { llvm::LLVMRustEnableTimePasses(); }
let mut pm = mk_pass_manager();
let td = mk_target_data(
/*bad*/copy sess.targ_cfg.target_strs.data_layout);
llvm::LLVMAddTargetData(td.lltd, pm.llpm);
// FIXME (#2812): run the linter here also, once there are llvm-c
// bindings for it.
// Generate a pre-optimization intermediate file if -save-temps was
// specified.
if opts.save_temps {
match opts.output_type {
output_type_bitcode => {
if opts.optimize != session::No {
let filename = output.with_filetype("no-opt.bc");
unsafe {
let opts = sess.opts;
if sess.time_llvm_passes() { llvm::LLVMRustEnableTimePasses(); }
let mut pm = mk_pass_manager();
let td = mk_target_data(
/*bad*/copy sess.targ_cfg.target_strs.data_layout);
llvm::LLVMAddTargetData(td.lltd, pm.llpm);
// FIXME (#2812): run the linter here also, once there are llvm-c
// bindings for it.
// Generate a pre-optimization intermediate file if -save-temps
// was specified.
if opts.save_temps {
match opts.output_type {
output_type_bitcode => {
if opts.optimize != session::No {
let filename = output.with_filetype("no-opt.bc");
str::as_c_str(filename.to_str(), |buf| {
llvm::LLVMWriteBitcodeToFile(llmod, buf)
});
}
}
_ => {
let filename = output.with_filetype("bc");
str::as_c_str(filename.to_str(), |buf| {
llvm::LLVMWriteBitcodeToFile(llmod, buf)
});
}
}
}
_ => {
let filename = output.with_filetype("bc");
str::as_c_str(filename.to_str(), |buf| {
llvm::LLVMWriteBitcodeToFile(llmod, buf)
});
}
}
}
if !sess.no_verify() { llvm::LLVMAddVerifierPass(pm.llpm); }
// FIXME (#2396): This is mostly a copy of the bits of opt's -O2 that
// are available in the C api.
// Also: We might want to add optimization levels like -O1, -O2,
// -Os, etc
// Also: Should we expose and use the pass lists used by the opt
// tool?
if opts.optimize != session::No {
let fpm = mk_pass_manager();
llvm::LLVMAddTargetData(td.lltd, fpm.llpm);
let FPMB = llvm::LLVMPassManagerBuilderCreate();
llvm::LLVMPassManagerBuilderSetOptLevel(FPMB, 2u as c_uint);
llvm::LLVMPassManagerBuilderPopulateFunctionPassManager(FPMB,
fpm.llpm);
llvm::LLVMPassManagerBuilderDispose(FPMB);
llvm::LLVMRunPassManager(fpm.llpm, llmod);
let mut threshold = 225;
if opts.optimize == session::Aggressive { threshold = 275; }
let MPMB = llvm::LLVMPassManagerBuilderCreate();
llvm::LLVMPassManagerBuilderSetOptLevel(MPMB,
opts.optimize as c_uint);
llvm::LLVMPassManagerBuilderSetSizeLevel(MPMB, False);
llvm::LLVMPassManagerBuilderSetDisableUnitAtATime(MPMB, False);
llvm::LLVMPassManagerBuilderSetDisableUnrollLoops(MPMB, False);
llvm::LLVMPassManagerBuilderSetDisableSimplifyLibCalls(MPMB,
False);
if threshold != 0u {
llvm::LLVMPassManagerBuilderUseInlinerWithThreshold
(MPMB, threshold as c_uint);
}
llvm::LLVMPassManagerBuilderPopulateModulePassManager(MPMB,
pm.llpm);
if !sess.no_verify() { llvm::LLVMAddVerifierPass(pm.llpm); }
// FIXME (#2396): This is mostly a copy of the bits of opt's -O2
// that are available in the C api.
// Also: We might want to add optimization levels like -O1, -O2,
// -Os, etc
// Also: Should we expose and use the pass lists used by the opt
// tool?
if opts.optimize != session::No {
let fpm = mk_pass_manager();
llvm::LLVMAddTargetData(td.lltd, fpm.llpm);
let FPMB = llvm::LLVMPassManagerBuilderCreate();
llvm::LLVMPassManagerBuilderSetOptLevel(FPMB, 2u as c_uint);
llvm::LLVMPassManagerBuilderPopulateFunctionPassManager(
FPMB, fpm.llpm);
llvm::LLVMPassManagerBuilderDispose(FPMB);
llvm::LLVMRunPassManager(fpm.llpm, llmod);
let mut threshold = 225;
if opts.optimize == session::Aggressive { threshold = 275; }
let MPMB = llvm::LLVMPassManagerBuilderCreate();
llvm::LLVMPassManagerBuilderSetOptLevel(MPMB,
opts.optimize as
c_uint);
llvm::LLVMPassManagerBuilderSetSizeLevel(MPMB, False);
llvm::LLVMPassManagerBuilderSetDisableUnitAtATime(MPMB,
False);
llvm::LLVMPassManagerBuilderSetDisableUnrollLoops(MPMB,
False);
llvm::LLVMPassManagerBuilderSetDisableSimplifyLibCalls(MPMB,
False);
if threshold != 0u {
llvm::LLVMPassManagerBuilderUseInlinerWithThreshold
(MPMB, threshold as c_uint);
}
llvm::LLVMPassManagerBuilderPopulateModulePassManager(
MPMB, pm.llpm);
llvm::LLVMPassManagerBuilderDispose(MPMB);
}
if !sess.no_verify() { llvm::LLVMAddVerifierPass(pm.llpm); }
if is_object_or_assembly_or_exe(opts.output_type) || opts.jit {
let LLVMOptNone = 0 as c_int; // -O0
let LLVMOptLess = 1 as c_int; // -O1
let LLVMOptDefault = 2 as c_int; // -O2, -Os
let LLVMOptAggressive = 3 as c_int; // -O3
let mut CodeGenOptLevel = match opts.optimize {
session::No => LLVMOptNone,
session::Less => LLVMOptLess,
session::Default => LLVMOptDefault,
session::Aggressive => LLVMOptAggressive
};
llvm::LLVMPassManagerBuilderDispose(MPMB);
}
if !sess.no_verify() { llvm::LLVMAddVerifierPass(pm.llpm); }
if is_object_or_assembly_or_exe(opts.output_type) || opts.jit {
let LLVMOptNone = 0 as c_int; // -O0
let LLVMOptLess = 1 as c_int; // -O1
let LLVMOptDefault = 2 as c_int; // -O2, -Os
let LLVMOptAggressive = 3 as c_int; // -O3
let mut CodeGenOptLevel = match opts.optimize {
session::No => LLVMOptNone,
session::Less => LLVMOptLess,
session::Default => LLVMOptDefault,
session::Aggressive => LLVMOptAggressive
};
if opts.jit {
// If we are using JIT, go ahead and create and
// execute the engine now.
// JIT execution takes ownership of the module,
// so don't dispose and return.
if opts.jit {
// If we are using JIT, go ahead and create and
// execute the engine now.
// JIT execution takes ownership of the module,
// so don't dispose and return.
jit::exec(sess, pm.llpm, llmod, CodeGenOptLevel, true);
jit::exec(sess, pm.llpm, llmod, CodeGenOptLevel, true);
if sess.time_llvm_passes() {
llvm::LLVMRustPrintPassTimings();
if sess.time_llvm_passes() {
llvm::LLVMRustPrintPassTimings();
}
return;
}
return;
}
let mut FileType;
if opts.output_type == output_type_object ||
opts.output_type == output_type_exe {
FileType = lib::llvm::ObjectFile;
} else { FileType = lib::llvm::AssemblyFile; }
// Write optimized bitcode if --save-temps was on.
let mut FileType;
if opts.output_type == output_type_object ||
opts.output_type == output_type_exe {
FileType = lib::llvm::ObjectFile;
} else { FileType = lib::llvm::AssemblyFile; }
// Write optimized bitcode if --save-temps was on.
if opts.save_temps {
// Always output the bitcode file with --save-temps
if opts.save_temps {
// Always output the bitcode file with --save-temps
let filename = output.with_filetype("opt.bc");
llvm::LLVMRunPassManager(pm.llpm, llmod);
str::as_c_str(filename.to_str(), |buf| {
llvm::LLVMWriteBitcodeToFile(llmod, buf)
});
pm = mk_pass_manager();
// Save the assembly file if -S is used
let filename = output.with_filetype("opt.bc");
llvm::LLVMRunPassManager(pm.llpm, llmod);
str::as_c_str(filename.to_str(), |buf| {
llvm::LLVMWriteBitcodeToFile(llmod, buf)
});
pm = mk_pass_manager();
// Save the assembly file if -S is used
if opts.output_type == output_type_assembly {
let _: () = str::as_c_str(
sess.targ_cfg.target_strs.target_triple,
|buf_t| {
str::as_c_str(output.to_str(), |buf_o| {
WriteOutputFile(
sess,
pm.llpm,
llmod,
buf_t,
buf_o,
lib::llvm::AssemblyFile as c_uint,
CodeGenOptLevel,
true)
})
});
}
if opts.output_type == output_type_assembly {
let _: () = str::as_c_str(
sess.targ_cfg.target_strs.target_triple,
|buf_t| {
str::as_c_str(output.to_str(), |buf_o| {
WriteOutputFile(
sess,
pm.llpm,
llmod,
buf_t,
buf_o,
lib::llvm::AssemblyFile as c_uint,
CodeGenOptLevel,
true)
})
});
}
// Save the object file for -c or --save-temps alone
// This .o is needed when an exe is built
if opts.output_type == output_type_object ||
opts.output_type == output_type_exe {
let _: () = str::as_c_str(
sess.targ_cfg.target_strs.target_triple,
|buf_t| {
str::as_c_str(output.to_str(), |buf_o| {
WriteOutputFile(
sess,
pm.llpm,
llmod,
buf_t,
buf_o,
lib::llvm::ObjectFile as c_uint,
CodeGenOptLevel,
true)
})
});
}
} else {
// If we aren't saving temps then just output the file
// type corresponding to the '-c' or '-S' flag used
// Save the object file for -c or --save-temps alone
// This .o is needed when an exe is built
if opts.output_type == output_type_object ||
opts.output_type == output_type_exe {
let _: () = str::as_c_str(
sess.targ_cfg.target_strs.target_triple,
|buf_t| {
......@@ -340,53 +372,36 @@ fn run_passes(sess: Session, llmod: ModuleRef, output: &Path) {
llmod,
buf_t,
buf_o,
lib::llvm::ObjectFile as c_uint,
FileType as c_uint,
CodeGenOptLevel,
true)
})
});
}
// Clean up and return
llvm::LLVMDisposeModule(llmod);
if sess.time_llvm_passes() {
llvm::LLVMRustPrintPassTimings();
}
return;
}
if opts.output_type == output_type_llvm_assembly {
// Given options "-S --emit-llvm": output LLVM assembly
str::as_c_str(output.to_str(), |buf_o| {
llvm::LLVMRustAddPrintModulePass(pm.llpm, llmod, buf_o)});
} else {
// If we aren't saving temps then just output the file
// type corresponding to the '-c' or '-S' flag used
let _: () = str::as_c_str(
sess.targ_cfg.target_strs.target_triple,
|buf_t| {
str::as_c_str(output.to_str(), |buf_o| {
WriteOutputFile(
sess,
pm.llpm,
llmod,
buf_t,
buf_o,
FileType as c_uint,
CodeGenOptLevel,
true)
})
});
// If only a bitcode file is asked for by using the
// '--emit-llvm' flag, then output it here
llvm::LLVMRunPassManager(pm.llpm, llmod);
str::as_c_str(output.to_str(),
|buf| llvm::LLVMWriteBitcodeToFile(llmod, buf) );
}
// Clean up and return
llvm::LLVMDisposeModule(llmod);
if sess.time_llvm_passes() { llvm::LLVMRustPrintPassTimings(); }
return;
}
if opts.output_type == output_type_llvm_assembly {
// Given options "-S --emit-llvm": output LLVM assembly
str::as_c_str(output.to_str(), |buf_o| {
llvm::LLVMRustAddPrintModulePass(pm.llpm, llmod, buf_o)});
} else {
// If only a bitcode file is asked for by using the '--emit-llvm'
// flag, then output it here
llvm::LLVMRunPassManager(pm.llpm, llmod);
str::as_c_str(output.to_str(),
|buf| llvm::LLVMWriteBitcodeToFile(llmod, buf) );
}
llvm::LLVMDisposeModule(llmod);
if sess.time_llvm_passes() { llvm::LLVMRustPrintPassTimings(); }
}
}
......
......@@ -542,7 +542,9 @@ fn build_session_options(+binary: ~str,
debugging_opts |= this_bit;
}
if debugging_opts & session::debug_llvm != 0 {
llvm::LLVMSetDebug(1);
unsafe {
llvm::LLVMSetDebug(1);
}
}
let jit = opt_present(matches, ~"jit");
......
此差异已折叠。
......@@ -1395,8 +1395,10 @@ fn compile_submatch(bcx: block,
switch => {
match trans_opt(bcx, opt) {
single_result(r) => {
unsafe {
llvm::LLVMAddCase(sw, r.val, opt_cx.llbb);
bcx = r.bcx;
}
}
_ => {
bcx.sess().bug(
......
此差异已折叠。
此差异已折叠。
......@@ -440,25 +440,27 @@ fn trans_call_inner(
Some(flag)
} else { None };
let (llfn, llenv) = match callee.data {
Fn(d) => {
(d.llfn, llvm::LLVMGetUndef(T_opaque_box_ptr(ccx)))
}
Method(d) => {
// Weird but true: we pass self in the *environment* slot!
let llself = PointerCast(bcx, d.llself,
T_opaque_box_ptr(ccx));
(d.llfn, llself)
}
Closure(d) => {
// Closures are represented as (llfn, llclosure) pair:
// load the requisite values out.
let pair = d.to_ref_llval(bcx);
let llfn = GEPi(bcx, pair, [0u, abi::fn_field_code]);
let llfn = Load(bcx, llfn);
let llenv = GEPi(bcx, pair, [0u, abi::fn_field_box]);
let llenv = Load(bcx, llenv);
(llfn, llenv)
let (llfn, llenv) = unsafe {
match callee.data {
Fn(d) => {
(d.llfn, llvm::LLVMGetUndef(T_opaque_box_ptr(ccx)))
}
Method(d) => {
// Weird but true: we pass self in the *environment* slot!
let llself = PointerCast(bcx, d.llself,
T_opaque_box_ptr(ccx));
(d.llfn, llself)
}
Closure(d) => {
// Closures are represented as (llfn, llclosure) pair:
// load the requisite values out.
let pair = d.to_ref_llval(bcx);
let llfn = GEPi(bcx, pair, [0u, abi::fn_field_code]);
let llfn = Load(bcx, llfn);
let llenv = GEPi(bcx, pair, [0u, abi::fn_field_box]);
let llenv = Load(bcx, llenv);
(llfn, llenv)
}
}
};
......@@ -493,8 +495,10 @@ fn trans_call_inner(
bcx = base::invoke(bcx, llfn, llargs);
match dest { // drop the value if it is not being saved.
expr::Ignore => {
if llvm::LLVMIsUndef(llretslot) != lib::llvm::True {
bcx = glue::drop_ty(bcx, llretslot, ret_ty);
unsafe {
if llvm::LLVMIsUndef(llretslot) != lib::llvm::True {
bcx = glue::drop_ty(bcx, llretslot, ret_ty);
}
}
}
expr::SaveIn(_) => { }
......@@ -545,7 +549,9 @@ fn trans_args(cx: block,
expr::SaveIn(dst) => dst,
expr::Ignore => {
if ty::type_is_nil(retty) {
llvm::LLVMGetUndef(T_ptr(T_nil()))
unsafe {
llvm::LLVMGetUndef(T_ptr(T_nil()))
}
} else {
alloc_ty(bcx, retty)
}
......@@ -662,7 +668,9 @@ fn trans_arg_expr(bcx: block,
// be inspected. It's important for the value
// to have type lldestty (the callee's expected type).
let llformal_ty = type_of::type_of(ccx, formal_ty.ty);
val = llvm::LLVMGetUndef(llformal_ty);
unsafe {
val = llvm::LLVMGetUndef(llformal_ty);
}
} else {
// FIXME(#3548) use the adjustments table
match autoref_arg {
......
......@@ -339,7 +339,9 @@ fn load_environment(fcx: fn_ctxt,
let ll =
str::as_c_str(~"load_env",
|buf|
llvm::LLVMAppendBasicBlock(fcx.llfn, buf));
unsafe {
llvm::LLVMAppendBasicBlock(fcx.llfn, buf)
});
fcx.llloadenv = Some(ll);
ll
}
......
......@@ -137,7 +137,11 @@ fn new_addrspace_gen() -> addrspace_gen {
struct BuilderRef_res {
B: BuilderRef,
drop { llvm::LLVMDisposeBuilder(self.B); }
drop {
unsafe {
llvm::LLVMDisposeBuilder(self.B);
}
}
}
fn BuilderRef_res(B: BuilderRef) -> BuilderRef_res {
......@@ -613,7 +617,11 @@ fn ty_str(tn: type_names, t: TypeRef) -> ~str {
return lib::llvm::type_to_str(tn, t);
}
fn val_ty(v: ValueRef) -> TypeRef { return llvm::LLVMTypeOf(v); }
fn val_ty(v: ValueRef) -> TypeRef {
unsafe {
return llvm::LLVMTypeOf(v);
}
}
fn val_str(tn: type_names, v: ValueRef) -> ~str {
return ty_str(tn, val_ty(v));
......@@ -621,12 +629,15 @@ fn val_str(tn: type_names, v: ValueRef) -> ~str {
// Returns the nth element of the given LLVM structure type.
fn struct_elt(llstructty: TypeRef, n: uint) -> TypeRef unsafe {
let elt_count = llvm::LLVMCountStructElementTypes(llstructty) as uint;
assert (n < elt_count);
let mut elt_tys = vec::from_elem(elt_count, T_nil());
llvm::LLVMGetStructElementTypes(llstructty,
ptr::to_mut_unsafe_ptr(&mut elt_tys[0]));
return llvm::LLVMGetElementType(elt_tys[n]);
unsafe {
let elt_count = llvm::LLVMCountStructElementTypes(llstructty) as uint;
assert (n < elt_count);
let mut elt_tys = vec::from_elem(elt_count, T_nil());
llvm::LLVMGetStructElementTypes(
llstructty,
ptr::to_mut_unsafe_ptr(&mut elt_tys[0]));
return llvm::LLVMGetElementType(elt_tys[n]);
}
}
fn in_scope_cx(cx: block, f: fn(scope_info)) {
......@@ -722,30 +733,34 @@ fn T_void() -> TypeRef {
// of 10 nil values will have 10-bit size -- but it doesn't seem like we
// have any other options until it's fixed upstream.
return llvm::LLVMVoidType();
unsafe {
return llvm::LLVMVoidType();
}
}
fn T_nil() -> TypeRef {
// NB: See above in T_void().
return llvm::LLVMInt1Type();
unsafe {
return llvm::LLVMInt1Type();
}
}
fn T_metadata() -> TypeRef { return llvm::LLVMMetadataType(); }
fn T_metadata() -> TypeRef { unsafe { return llvm::LLVMMetadataType(); } }
fn T_i1() -> TypeRef { return llvm::LLVMInt1Type(); }
fn T_i1() -> TypeRef { unsafe { return llvm::LLVMInt1Type(); } }
fn T_i8() -> TypeRef { return llvm::LLVMInt8Type(); }
fn T_i8() -> TypeRef { unsafe { return llvm::LLVMInt8Type(); } }
fn T_i16() -> TypeRef { return llvm::LLVMInt16Type(); }
fn T_i16() -> TypeRef { unsafe { return llvm::LLVMInt16Type(); } }
fn T_i32() -> TypeRef { return llvm::LLVMInt32Type(); }
fn T_i32() -> TypeRef { unsafe { return llvm::LLVMInt32Type(); } }
fn T_i64() -> TypeRef { return llvm::LLVMInt64Type(); }
fn T_i64() -> TypeRef { unsafe { return llvm::LLVMInt64Type(); } }
fn T_f32() -> TypeRef { return llvm::LLVMFloatType(); }
fn T_f32() -> TypeRef { unsafe { return llvm::LLVMFloatType(); } }
fn T_f64() -> TypeRef { return llvm::LLVMDoubleType(); }
fn T_f64() -> TypeRef { unsafe { return llvm::LLVMDoubleType(); } }
fn T_bool() -> TypeRef { return T_i1(); }
......@@ -811,25 +826,39 @@ fn T_fn_pair(cx: @crate_ctxt, tfn: TypeRef) -> TypeRef {
}
fn T_ptr(t: TypeRef) -> TypeRef {
return llvm::LLVMPointerType(t, default_addrspace);
unsafe {
return llvm::LLVMPointerType(t, default_addrspace);
}
}
fn T_root(t: TypeRef, addrspace: addrspace) -> TypeRef {
return llvm::LLVMPointerType(t, addrspace);
unsafe {
return llvm::LLVMPointerType(t, addrspace);
}
}
fn T_struct(elts: ~[TypeRef]) -> TypeRef unsafe {
return llvm::LLVMStructType(to_ptr(elts), elts.len() as c_uint, False);
unsafe {
return llvm::LLVMStructType(to_ptr(elts),
elts.len() as c_uint,
False);
}
}
fn T_named_struct(name: ~str) -> TypeRef {
let c = llvm::LLVMGetGlobalContext();
return str::as_c_str(name, |buf| llvm::LLVMStructCreateNamed(c, buf));
unsafe {
let c = llvm::LLVMGetGlobalContext();
return str::as_c_str(name, |buf| llvm::LLVMStructCreateNamed(c, buf));
}
}
fn set_struct_body(t: TypeRef, elts: ~[TypeRef]) unsafe {
llvm::LLVMStructSetBody(t, to_ptr(elts),
elts.len() as c_uint, False);
unsafe {
llvm::LLVMStructSetBody(t,
to_ptr(elts),
elts.len() as c_uint,
False);
}
}
fn T_empty_struct() -> TypeRef { return T_struct(~[]); }
......@@ -865,14 +894,16 @@ fn T_task(targ_cfg: @session::config) -> TypeRef {
fn T_tydesc_field(cx: @crate_ctxt, field: uint) -> TypeRef unsafe {
// Bit of a kludge: pick the fn typeref out of the tydesc..
let mut tydesc_elts: ~[TypeRef] =
vec::from_elem::<TypeRef>(abi::n_tydesc_fields,
T_nil());
llvm::LLVMGetStructElementTypes(
cx.tydesc_type,
ptr::to_mut_unsafe_ptr(&mut tydesc_elts[0]));
let t = llvm::LLVMGetElementType(tydesc_elts[field]);
return t;
unsafe {
let mut tydesc_elts: ~[TypeRef] =
vec::from_elem::<TypeRef>(abi::n_tydesc_fields,
T_nil());
llvm::LLVMGetStructElementTypes(
cx.tydesc_type,
ptr::to_mut_unsafe_ptr(&mut tydesc_elts[0]));
let t = llvm::LLVMGetElementType(tydesc_elts[field]);
return t;
}
}
fn T_generic_glue_fn(cx: @crate_ctxt) -> TypeRef {
......@@ -904,7 +935,9 @@ fn T_tydesc(targ_cfg: @session::config) -> TypeRef {
}
fn T_array(t: TypeRef, n: uint) -> TypeRef {
return llvm::LLVMArrayType(t, n as c_uint);
unsafe {
return llvm::LLVMArrayType(t, n as c_uint);
}
}
// Interior vector.
......@@ -947,7 +980,9 @@ fn T_box(cx: @crate_ctxt, t: TypeRef) -> TypeRef {
}
fn T_box_ptr(t: TypeRef) -> TypeRef {
return llvm::LLVMPointerType(t, gc_box_addrspace);
unsafe {
return llvm::LLVMPointerType(t, gc_box_addrspace);
}
}
fn T_opaque_box(cx: @crate_ctxt) -> TypeRef {
......@@ -963,7 +998,9 @@ fn T_unique(cx: @crate_ctxt, t: TypeRef) -> TypeRef {
}
fn T_unique_ptr(t: TypeRef) -> TypeRef {
return llvm::LLVMPointerType(t, gc_box_addrspace);
unsafe {
return llvm::LLVMPointerType(t, gc_box_addrspace);
}
}
fn T_port(cx: @crate_ctxt, _t: TypeRef) -> TypeRef {
......@@ -1042,14 +1079,22 @@ fn T_opaque_trait(cx: @crate_ctxt, vstore: ty::vstore) -> TypeRef {
// LLVM constant constructors.
fn C_null(t: TypeRef) -> ValueRef { return llvm::LLVMConstNull(t); }
fn C_null(t: TypeRef) -> ValueRef {
unsafe {
return llvm::LLVMConstNull(t);
}
}
fn C_integral(t: TypeRef, u: u64, sign_extend: Bool) -> ValueRef {
return llvm::LLVMConstInt(t, u, sign_extend);
unsafe {
return llvm::LLVMConstInt(t, u, sign_extend);
}
}
fn C_floating(s: ~str, t: TypeRef) -> ValueRef {
return str::as_c_str(s, |buf| llvm::LLVMConstRealOfString(t, buf));
unsafe {
return str::as_c_str(s, |buf| llvm::LLVMConstRealOfString(t, buf));
}
}
fn C_nil() -> ValueRef {
......@@ -1084,92 +1129,115 @@ fn C_uint(cx: @crate_ctxt, i: uint) -> ValueRef {
// This is a 'c-like' raw string, which differs from
// our boxed-and-length-annotated strings.
fn C_cstr(cx: @crate_ctxt, +s: ~str) -> ValueRef {
match cx.const_cstr_cache.find(s) {
Some(llval) => return llval,
None => ()
}
unsafe {
match cx.const_cstr_cache.find(s) {
Some(llval) => return llval,
None => ()
}
let sc = do str::as_c_str(s) |buf| {
llvm::LLVMConstString(buf, str::len(s) as c_uint, False)
};
let g =
str::as_c_str(fmt!("str%u", (cx.names)(~"str").repr),
|buf| llvm::LLVMAddGlobal(cx.llmod, val_ty(sc), buf));
llvm::LLVMSetInitializer(g, sc);
llvm::LLVMSetGlobalConstant(g, True);
lib::llvm::SetLinkage(g, lib::llvm::InternalLinkage);
let sc = do str::as_c_str(s) |buf| {
llvm::LLVMConstString(buf, str::len(s) as c_uint, False)
};
let g =
str::as_c_str(fmt!("str%u", (cx.names)(~"str").repr),
|buf| llvm::LLVMAddGlobal(cx.llmod, val_ty(sc), buf));
llvm::LLVMSetInitializer(g, sc);
llvm::LLVMSetGlobalConstant(g, True);
lib::llvm::SetLinkage(g, lib::llvm::InternalLinkage);
cx.const_cstr_cache.insert(s, g);
cx.const_cstr_cache.insert(s, g);
return g;
return g;
}
}
// NB: Do not use `do_spill_noroot` to make this into a constant string, or
// you will be kicked off fast isel. See issue #4352 for an example of this.
fn C_estr_slice(cx: @crate_ctxt, +s: ~str) -> ValueRef {
let len = str::len(s);
let cs = llvm::LLVMConstPointerCast(C_cstr(cx, s), T_ptr(T_i8()));
C_struct(~[cs, C_uint(cx, len + 1u /* +1 for null */)])
unsafe {
let len = str::len(s);
let cs = llvm::LLVMConstPointerCast(C_cstr(cx, s), T_ptr(T_i8()));
C_struct(~[cs, C_uint(cx, len + 1u /* +1 for null */)])
}
}
// Returns a Plain Old LLVM String:
fn C_postr(s: ~str) -> ValueRef {
return do str::as_c_str(s) |buf| {
llvm::LLVMConstString(buf, str::len(s) as c_uint, False)
};
unsafe {
return do str::as_c_str(s) |buf| {
llvm::LLVMConstString(buf, str::len(s) as c_uint, False)
};
}
}
fn C_zero_byte_arr(size: uint) -> ValueRef unsafe {
let mut i = 0u;
let mut elts: ~[ValueRef] = ~[];
while i < size { elts.push(C_u8(0u)); i += 1u; }
return llvm::LLVMConstArray(T_i8(), vec::raw::to_ptr(elts),
elts.len() as c_uint);
unsafe {
let mut i = 0u;
let mut elts: ~[ValueRef] = ~[];
while i < size { elts.push(C_u8(0u)); i += 1u; }
return llvm::LLVMConstArray(T_i8(),
vec::raw::to_ptr(elts),
elts.len() as c_uint);
}
}
fn C_struct(elts: &[ValueRef]) -> ValueRef {
do vec::as_imm_buf(elts) |ptr, len| {
llvm::LLVMConstStruct(ptr, len as c_uint, False)
unsafe {
do vec::as_imm_buf(elts) |ptr, len| {
llvm::LLVMConstStruct(ptr, len as c_uint, False)
}
}
}
fn C_named_struct(T: TypeRef, elts: &[ValueRef]) -> ValueRef {
do vec::as_imm_buf(elts) |ptr, len| {
llvm::LLVMConstNamedStruct(T, ptr, len as c_uint)
unsafe {
do vec::as_imm_buf(elts) |ptr, len| {
llvm::LLVMConstNamedStruct(T, ptr, len as c_uint)
}
}
}
fn C_array(ty: TypeRef, elts: ~[ValueRef]) -> ValueRef unsafe {
return llvm::LLVMConstArray(ty, vec::raw::to_ptr(elts),
elts.len() as c_uint);
unsafe {
return llvm::LLVMConstArray(ty, vec::raw::to_ptr(elts),
elts.len() as c_uint);
}
}
fn C_bytes(bytes: ~[u8]) -> ValueRef unsafe {
return llvm::LLVMConstString(
cast::reinterpret_cast(&vec::raw::to_ptr(bytes)),
bytes.len() as c_uint, True);
unsafe {
return llvm::LLVMConstString(
cast::reinterpret_cast(&vec::raw::to_ptr(bytes)),
bytes.len() as c_uint, True);
}
}
fn C_bytes_plus_null(bytes: ~[u8]) -> ValueRef unsafe {
return llvm::LLVMConstString(
cast::reinterpret_cast(&vec::raw::to_ptr(bytes)),
bytes.len() as c_uint, False);
unsafe {
return llvm::LLVMConstString(
cast::reinterpret_cast(&vec::raw::to_ptr(bytes)),
bytes.len() as c_uint, False);
}
}
fn C_shape(ccx: @crate_ctxt, +bytes: ~[u8]) -> ValueRef {
let llshape = C_bytes_plus_null(bytes);
let name = fmt!("shape%u", (ccx.names)(~"shape").repr);
let llglobal = str::as_c_str(name, |buf| {
llvm::LLVMAddGlobal(ccx.llmod, val_ty(llshape), buf)
});
llvm::LLVMSetInitializer(llglobal, llshape);
llvm::LLVMSetGlobalConstant(llglobal, True);
lib::llvm::SetLinkage(llglobal, lib::llvm::InternalLinkage);
return llvm::LLVMConstPointerCast(llglobal, T_ptr(T_i8()));
unsafe {
let llshape = C_bytes_plus_null(bytes);
let name = fmt!("shape%u", (ccx.names)(~"shape").repr);
let llglobal = str::as_c_str(name, |buf| {
llvm::LLVMAddGlobal(ccx.llmod, val_ty(llshape), buf)
});
llvm::LLVMSetInitializer(llglobal, llshape);
llvm::LLVMSetGlobalConstant(llglobal, True);
lib::llvm::SetLinkage(llglobal, lib::llvm::InternalLinkage);
return llvm::LLVMConstPointerCast(llglobal, T_ptr(T_i8()));
}
}
fn get_param(fndecl: ValueRef, param: uint) -> ValueRef {
llvm::LLVMGetParam(fndecl, param as c_uint)
unsafe {
llvm::LLVMGetParam(fndecl, param as c_uint)
}
}
// Used to identify cached monomorphized functions and vtables
......
此差异已折叠。
......@@ -186,12 +186,15 @@ fn trans_log(log_ex: @ast::expr,
} else {
let s = link::mangle_internal_name_by_path_and_seq(
ccx, modpath, ~"loglevel");
let global = str::as_c_str(s, |buf| {
llvm::LLVMAddGlobal(ccx.llmod, T_i32(), buf)
});
llvm::LLVMSetGlobalConstant(global, False);
llvm::LLVMSetInitializer(global, C_null(T_i32()));
lib::llvm::SetLinkage(global, lib::llvm::InternalLinkage);
let global;
unsafe {
global = str::as_c_str(s, |buf| {
llvm::LLVMAddGlobal(ccx.llmod, T_i32(), buf)
});
llvm::LLVMSetGlobalConstant(global, False);
llvm::LLVMSetInitializer(global, C_null(T_i32()));
lib::llvm::SetLinkage(global, lib::llvm::InternalLinkage);
}
ccx.module_data.insert(modname, global);
global
};
......
......@@ -69,7 +69,9 @@
fn llstr(s: ~str) -> ValueRef {
str::as_c_str(s, |sbuf| {
llvm::LLVMMDString(sbuf, str::len(s) as libc::c_uint)
unsafe {
llvm::LLVMMDString(sbuf, str::len(s) as libc::c_uint)
}
})
}
fn lltag(lltag: int) -> ValueRef {
......@@ -85,8 +87,10 @@ fn lli1(bval: bool) -> ValueRef {
C_bool(bval)
}
fn llmdnode(elems: ~[ValueRef]) -> ValueRef unsafe {
llvm::LLVMMDNode(vec::raw::to_ptr(elems),
vec::len(elems) as libc::c_uint)
unsafe {
llvm::LLVMMDNode(vec::raw::to_ptr(elems),
vec::len(elems) as libc::c_uint)
}
}
fn llunused() -> ValueRef {
lli32(0x0)
......@@ -97,7 +101,9 @@ fn llnull() -> ValueRef unsafe {
fn add_named_metadata(cx: @crate_ctxt, name: ~str, val: ValueRef) {
str::as_c_str(name, |sbuf| {
llvm::LLVMAddNamedMetadataOperand(cx.llmod, sbuf, val)
unsafe {
llvm::LLVMAddNamedMetadataOperand(cx.llmod, sbuf, val)
}
})
}
......@@ -744,7 +750,9 @@ fn update_source_pos(cx: block, s: span) {
blockmd.node,
llnull()];
let dbgscope = llmdnode(scopedata);
llvm::LLVMSetCurrentDebugLocation(trans::build::B(cx), dbgscope);
unsafe {
llvm::LLVMSetCurrentDebugLocation(trans::build::B(cx), dbgscope);
}
}
fn create_function(fcx: fn_ctxt) -> @metadata<subprogram_md> {
......
......@@ -1483,15 +1483,19 @@ fn trans_overloaded_op(bcx: block,
fn int_cast(bcx: block, lldsttype: TypeRef, llsrctype: TypeRef,
llsrc: ValueRef, signed: bool) -> ValueRef {
let _icx = bcx.insn_ctxt("int_cast");
let srcsz = llvm::LLVMGetIntTypeWidth(llsrctype);
let dstsz = llvm::LLVMGetIntTypeWidth(lldsttype);
return if dstsz == srcsz {
BitCast(bcx, llsrc, lldsttype)
} else if srcsz > dstsz {
TruncOrBitCast(bcx, llsrc, lldsttype)
} else if signed {
SExtOrBitCast(bcx, llsrc, lldsttype)
} else { ZExtOrBitCast(bcx, llsrc, lldsttype) };
unsafe {
let srcsz = llvm::LLVMGetIntTypeWidth(llsrctype);
let dstsz = llvm::LLVMGetIntTypeWidth(lldsttype);
return if dstsz == srcsz {
BitCast(bcx, llsrc, lldsttype)
} else if srcsz > dstsz {
TruncOrBitCast(bcx, llsrc, lldsttype)
} else if signed {
SExtOrBitCast(bcx, llsrc, lldsttype)
} else {
ZExtOrBitCast(bcx, llsrc, lldsttype)
};
}
}
fn float_cast(bcx: block, lldsttype: TypeRef, llsrctype: TypeRef,
......
此差异已折叠。
......@@ -79,13 +79,17 @@ fn simplifier(tcx: ty::ctxt, typ: ty::t) -> ty::t {
// Returns the number of bytes clobbered by a Store to this type.
pub fn llsize_of_store(cx: @crate_ctxt, t: TypeRef) -> uint {
return llvm::LLVMStoreSizeOfType(cx.td.lltd, t) as uint;
unsafe {
return llvm::LLVMStoreSizeOfType(cx.td.lltd, t) as uint;
}
}
// Returns the number of bytes between successive elements of type T in an
// array of T. This is the "ABI" size. It includes any ABI-mandated padding.
pub fn llsize_of_alloc(cx: @crate_ctxt, t: TypeRef) -> uint {
return llvm::LLVMABISizeOfType(cx.td.lltd, t) as uint;
unsafe {
return llvm::LLVMABISizeOfType(cx.td.lltd, t) as uint;
}
}
// Returns, as near as we can figure, the "real" size of a type. As in, the
......@@ -97,18 +101,22 @@ pub fn llsize_of_alloc(cx: @crate_ctxt, t: TypeRef) -> uint {
// at the codegen level! In general you should prefer `llbitsize_of_real`
// below.
pub fn llsize_of_real(cx: @crate_ctxt, t: TypeRef) -> uint {
let nbits = llvm::LLVMSizeOfTypeInBits(cx.td.lltd, t) as uint;
if nbits & 7u != 0u {
// Not an even number of bytes, spills into "next" byte.
1u + (nbits >> 3)
} else {
nbits >> 3
unsafe {
let nbits = llvm::LLVMSizeOfTypeInBits(cx.td.lltd, t) as uint;
if nbits & 7u != 0u {
// Not an even number of bytes, spills into "next" byte.
1u + (nbits >> 3)
} else {
nbits >> 3
}
}
}
/// Returns the "real" size of the type in bits.
pub fn llbitsize_of_real(cx: @crate_ctxt, t: TypeRef) -> uint {
llvm::LLVMSizeOfTypeInBits(cx.td.lltd, t) as uint
unsafe {
llvm::LLVMSizeOfTypeInBits(cx.td.lltd, t) as uint
}
}
// Returns the "default" size of t, which is calculated by casting null to a
......@@ -117,8 +125,11 @@ pub fn llbitsize_of_real(cx: @crate_ctxt, t: TypeRef) -> uint {
// (i.e. including alignment-padding), but goodness knows which alignment it
// winds up using. Probably the ABI one? Not recommended.
pub fn llsize_of(cx: @crate_ctxt, t: TypeRef) -> ValueRef {
return llvm::LLVMConstIntCast(lib::llvm::llvm::LLVMSizeOf(t), cx.int_type,
False);
unsafe {
return llvm::LLVMConstIntCast(lib::llvm::llvm::LLVMSizeOf(t),
cx.int_type,
False);
}
}
// Returns the preferred alignment of the given type for the current target.
......@@ -126,22 +137,28 @@ pub fn llsize_of(cx: @crate_ctxt, t: TypeRef) -> ValueRef {
// packing the type into structs. This will be used for things like
// allocations inside a stack frame, which LLVM has a free hand in.
pub fn llalign_of_pref(cx: @crate_ctxt, t: TypeRef) -> uint {
return llvm::LLVMPreferredAlignmentOfType(cx.td.lltd, t) as uint;
unsafe {
return llvm::LLVMPreferredAlignmentOfType(cx.td.lltd, t) as uint;
}
}
// Returns the minimum alignment of a type required by the plattform.
// This is the alignment that will be used for struct fields, arrays,
// and similar ABI-mandated things.
pub fn llalign_of_min(cx: @crate_ctxt, t: TypeRef) -> uint {
return llvm::LLVMABIAlignmentOfType(cx.td.lltd, t) as uint;
unsafe {
return llvm::LLVMABIAlignmentOfType(cx.td.lltd, t) as uint;
}
}
// Returns the "default" alignment of t, which is calculated by casting
// null to a record containing a single-bit followed by a t value, then
// doing gep(0,1) to get at the trailing (and presumably padded) t cell.
pub fn llalign_of(cx: @crate_ctxt, t: TypeRef) -> ValueRef {
return llvm::LLVMConstIntCast(
lib::llvm::llvm::LLVMAlignOf(t), cx.int_type, False);
unsafe {
return llvm::LLVMConstIntCast(
lib::llvm::llvm::LLVMAlignOf(t), cx.int_type, False);
}
}
// Computes the size of the data part of an enum.
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册