librustc: Make all external functions unsafe. r=tjc

This commit is contained in:
Patrick Walton
2013-01-10 21:23:07 -08:00
parent d97ab7888f
commit ca71c6ec5b
55 changed files with 4279 additions and 3101 deletions
+11 -9
View File
@@ -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;
}
+3 -3
View File
@@ -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"]
+1 -1
View File
@@ -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;
}
+95 -94
View File
@@ -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
+77 -1
View File
@@ -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
+84 -5
View File
@@ -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; }
+8 -8
View File
@@ -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.
+18 -6
View File
@@ -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 {
+5 -3
View File
@@ -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 {
+128 -67
View File
@@ -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 { 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;
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 seek(&self, offset: int, whence: SeekStyle) {
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
+200 -194
View File
@@ -1013,116 +1013,118 @@ pub mod c95 {
#[nolink]
#[abi = "cdecl"]
pub extern mod ctype {
fn isalnum(c: c_int) -> c_int;
fn isalpha(c: c_int) -> c_int;
fn iscntrl(c: c_int) -> c_int;
fn isdigit(c: c_int) -> c_int;
fn isgraph(c: c_int) -> c_int;
fn islower(c: c_int) -> c_int;
fn isprint(c: c_int) -> c_int;
fn ispunct(c: c_int) -> c_int;
fn isspace(c: c_int) -> c_int;
fn isupper(c: c_int) -> c_int;
fn isxdigit(c: c_int) -> c_int;
fn tolower(c: c_char) -> c_char;
fn toupper(c: c_char) -> c_char;
unsafe fn isalnum(c: c_int) -> c_int;
unsafe fn isalpha(c: c_int) -> c_int;
unsafe fn iscntrl(c: c_int) -> c_int;
unsafe fn isdigit(c: c_int) -> c_int;
unsafe fn isgraph(c: c_int) -> c_int;
unsafe fn islower(c: c_int) -> c_int;
unsafe fn isprint(c: c_int) -> c_int;
unsafe fn ispunct(c: c_int) -> c_int;
unsafe fn isspace(c: c_int) -> c_int;
unsafe fn isupper(c: c_int) -> c_int;
unsafe fn isxdigit(c: c_int) -> c_int;
unsafe fn tolower(c: c_char) -> c_char;
unsafe fn toupper(c: c_char) -> c_char;
}
#[nolink]
#[abi = "cdecl"]
pub extern mod stdio {
fn fopen(filename: *c_char, mode: *c_char) -> *FILE;
fn freopen(filename: *c_char, mode: *c_char,
unsafe fn fopen(filename: *c_char, mode: *c_char) -> *FILE;
unsafe fn freopen(filename: *c_char, mode: *c_char,
file: *FILE) -> *FILE;
fn fflush(file: *FILE) -> c_int;
fn fclose(file: *FILE) -> c_int;
fn remove(filename: *c_char) -> c_int;
fn rename(oldname: *c_char, newname: *c_char) -> c_int;
fn tmpfile() -> *FILE;
fn setvbuf(stream: *FILE, buffer: *c_char,
unsafe fn fflush(file: *FILE) -> c_int;
unsafe fn fclose(file: *FILE) -> c_int;
unsafe fn remove(filename: *c_char) -> c_int;
unsafe fn rename(oldname: *c_char, newname: *c_char) -> c_int;
unsafe fn tmpfile() -> *FILE;
unsafe fn setvbuf(stream: *FILE, buffer: *c_char,
mode: c_int, size: size_t) -> c_int;
fn setbuf(stream: *FILE, buf: *c_char);
unsafe fn setbuf(stream: *FILE, buf: *c_char);
// Omitted: printf and scanf variants.
fn fgetc(stream: *FILE) -> c_int;
fn fgets(buf: *mut c_char, n: c_int,
unsafe fn fgetc(stream: *FILE) -> c_int;
unsafe fn fgets(buf: *mut c_char, n: c_int,
stream: *FILE) -> *c_char;
fn fputc(c: c_int, stream: *FILE) -> c_int;
fn fputs(s: *c_char, stream: *FILE) -> *c_char;
unsafe fn fputc(c: c_int, stream: *FILE) -> c_int;
unsafe fn fputs(s: *c_char, stream: *FILE) -> *c_char;
// Omitted: getc, getchar (might be macros).
// Omitted: gets, so ridiculously unsafe that it should not
// survive.
// Omitted: putc, putchar (might be macros).
fn puts(s: *c_char) -> c_int;
fn ungetc(c: c_int, stream: *FILE) -> c_int;
fn fread(ptr: *mut c_void, size: size_t,
unsafe fn puts(s: *c_char) -> c_int;
unsafe fn ungetc(c: c_int, stream: *FILE) -> c_int;
unsafe fn fread(ptr: *mut c_void, size: size_t,
nobj: size_t, stream: *FILE) -> size_t;
fn fwrite(ptr: *c_void, size: size_t,
unsafe fn fwrite(ptr: *c_void, size: size_t,
nobj: size_t, stream: *FILE) -> size_t;
fn fseek(stream: *FILE, offset: c_long,
unsafe fn fseek(stream: *FILE, offset: c_long,
whence: c_int) -> c_int;
fn ftell(stream: *FILE) -> c_long;
fn rewind(stream: *FILE);
fn fgetpos(stream: *FILE, ptr: *fpos_t) -> c_int;
fn fsetpos(stream: *FILE, ptr: *fpos_t) -> c_int;
fn feof(stream: *FILE) -> c_int;
fn ferror(stream: *FILE) -> c_int;
fn perror(s: *c_char);
unsafe fn ftell(stream: *FILE) -> c_long;
unsafe fn rewind(stream: *FILE);
unsafe fn fgetpos(stream: *FILE, ptr: *fpos_t) -> c_int;
unsafe fn fsetpos(stream: *FILE, ptr: *fpos_t) -> c_int;
unsafe fn feof(stream: *FILE) -> c_int;
unsafe fn ferror(stream: *FILE) -> c_int;
unsafe fn perror(s: *c_char);
}
#[nolink]
#[abi = "cdecl"]
pub extern mod stdlib {
fn abs(i: c_int) -> c_int;
fn labs(i: c_long) -> c_long;
unsafe fn abs(i: c_int) -> c_int;
unsafe fn labs(i: c_long) -> c_long;
// Omitted: div, ldiv (return pub type incomplete).
fn atof(s: *c_char) -> c_double;
fn atoi(s: *c_char) -> c_int;
fn strtod(s: *c_char, endp: **c_char) -> c_double;
fn strtol(s: *c_char, endp: **c_char, base: c_int) -> c_long;
fn strtoul(s: *c_char, endp: **c_char,
base: c_int) -> c_ulong;
fn calloc(nobj: size_t, size: size_t) -> *c_void;
fn malloc(size: size_t) -> *c_void;
fn realloc(p: *c_void, size: size_t) -> *c_void;
fn free(p: *c_void);
fn abort() -> !;
fn exit(status: c_int) -> !;
unsafe fn atof(s: *c_char) -> c_double;
unsafe fn atoi(s: *c_char) -> c_int;
unsafe fn strtod(s: *c_char, endp: **c_char) -> c_double;
unsafe fn strtol(s: *c_char, endp: **c_char, base: c_int)
-> c_long;
unsafe fn strtoul(s: *c_char, endp: **c_char, base: c_int)
-> c_ulong;
unsafe fn calloc(nobj: size_t, size: size_t) -> *c_void;
unsafe fn malloc(size: size_t) -> *c_void;
unsafe fn realloc(p: *c_void, size: size_t) -> *c_void;
unsafe fn free(p: *c_void);
unsafe fn abort() -> !;
unsafe fn exit(status: c_int) -> !;
// Omitted: atexit.
fn system(s: *c_char) -> c_int;
fn getenv(s: *c_char) -> *c_char;
unsafe fn system(s: *c_char) -> c_int;
unsafe fn getenv(s: *c_char) -> *c_char;
// Omitted: bsearch, qsort
fn rand() -> c_int;
fn srand(seed: c_uint);
unsafe fn rand() -> c_int;
unsafe fn srand(seed: c_uint);
}
#[nolink]
#[abi = "cdecl"]
pub extern mod string {
fn strcpy(dst: *c_char, src: *c_char) -> *c_char;
fn strncpy(dst: *c_char, src: *c_char, n: size_t) -> *c_char;
fn strcat(s: *c_char, ct: *c_char) -> *c_char;
fn strncat(s: *c_char, ct: *c_char, n: size_t) -> *c_char;
fn strcmp(cs: *c_char, ct: *c_char) -> c_int;
fn strncmp(cs: *c_char, ct: *c_char, n: size_t) -> c_int;
fn strcoll(cs: *c_char, ct: *c_char) -> c_int;
fn strchr(cs: *c_char, c: c_int) -> *c_char;
fn strrchr(cs: *c_char, c: c_int) -> *c_char;
fn strspn(cs: *c_char, ct: *c_char) -> size_t;
fn strcspn(cs: *c_char, ct: *c_char) -> size_t;
fn strpbrk(cs: *c_char, ct: *c_char) -> *c_char;
fn strstr(cs: *c_char, ct: *c_char) -> *c_char;
fn strlen(cs: *c_char) -> size_t;
fn strerror(n: c_int) -> *c_char;
fn strtok(s: *c_char, t: *c_char) -> *c_char;
fn strxfrm(s: *c_char, ct: *c_char, n: size_t) -> size_t;
fn memcpy(s: *c_void, ct: *c_void, n: size_t) -> *c_void;
fn memmove(s: *c_void, ct: *c_void, n: size_t) -> *c_void;
fn memcmp(cx: *c_void, ct: *c_void, n: size_t) -> c_int;
fn memchr(cx: *c_void, c: c_int, n: size_t) -> *c_void;
fn memset(s: *c_void, c: c_int, n: size_t) -> *c_void;
unsafe fn strcpy(dst: *c_char, src: *c_char) -> *c_char;
unsafe fn strncpy(dst: *c_char, src: *c_char, n: size_t)
-> *c_char;
unsafe fn strcat(s: *c_char, ct: *c_char) -> *c_char;
unsafe fn strncat(s: *c_char, ct: *c_char, n: size_t) -> *c_char;
unsafe fn strcmp(cs: *c_char, ct: *c_char) -> c_int;
unsafe fn strncmp(cs: *c_char, ct: *c_char, n: size_t) -> c_int;
unsafe fn strcoll(cs: *c_char, ct: *c_char) -> c_int;
unsafe fn strchr(cs: *c_char, c: c_int) -> *c_char;
unsafe fn strrchr(cs: *c_char, c: c_int) -> *c_char;
unsafe fn strspn(cs: *c_char, ct: *c_char) -> size_t;
unsafe fn strcspn(cs: *c_char, ct: *c_char) -> size_t;
unsafe fn strpbrk(cs: *c_char, ct: *c_char) -> *c_char;
unsafe fn strstr(cs: *c_char, ct: *c_char) -> *c_char;
unsafe fn strlen(cs: *c_char) -> size_t;
unsafe fn strerror(n: c_int) -> *c_char;
unsafe fn strtok(s: *c_char, t: *c_char) -> *c_char;
unsafe fn strxfrm(s: *c_char, ct: *c_char, n: size_t) -> size_t;
unsafe fn memcpy(s: *c_void, ct: *c_void, n: size_t) -> *c_void;
unsafe fn memmove(s: *c_void, ct: *c_void, n: size_t) -> *c_void;
unsafe fn memcmp(cx: *c_void, ct: *c_void, n: size_t) -> c_int;
unsafe fn memchr(cx: *c_void, c: c_int, n: size_t) -> *c_void;
unsafe fn memset(s: *c_void, c: c_int, n: size_t) -> *c_void;
}
}
@@ -1141,16 +1143,16 @@ pub mod posix88 {
use libc::types::os::arch::c95::{c_int, c_char};
#[link_name = "_chmod"]
fn chmod(path: *c_char, mode: c_int) -> c_int;
unsafe fn chmod(path: *c_char, mode: c_int) -> c_int;
#[link_name = "_mkdir"]
fn mkdir(path: *c_char) -> c_int;
unsafe fn mkdir(path: *c_char) -> c_int;
#[link_name = "_fstat64"]
fn fstat(fildes: c_int, buf: *mut stat) -> c_int;
unsafe fn fstat(fildes: c_int, buf: *mut stat) -> c_int;
#[link_name = "_stat64"]
fn stat(path: *c_char, buf: *mut stat) -> c_int;
unsafe fn stat(path: *c_char, buf: *mut stat) -> c_int;
}
#[nolink]
@@ -1160,16 +1162,16 @@ pub mod posix88 {
use libc::types::os::arch::c95::{c_int, c_char};
#[link_name = "_popen"]
fn popen(command: *c_char, mode: *c_char) -> *FILE;
unsafe fn popen(command: *c_char, mode: *c_char) -> *FILE;
#[link_name = "_pclose"]
fn pclose(stream: *FILE) -> c_int;
unsafe fn pclose(stream: *FILE) -> c_int;
#[link_name = "_fdopen"]
fn fdopen(fd: c_int, mode: *c_char) -> *FILE;
unsafe fn fdopen(fd: c_int, mode: *c_char) -> *FILE;
#[link_name = "_fileno"]
fn fileno(stream: *FILE) -> c_int;
unsafe fn fileno(stream: *FILE) -> c_int;
}
#[nolink]
@@ -1178,10 +1180,10 @@ pub mod posix88 {
use libc::types::os::arch::c95::{c_int, c_char};
#[link_name = "_open"]
fn open(path: *c_char, oflag: c_int, mode: c_int) -> c_int;
unsafe fn open(path: *c_char, oflag: c_int, mode: c_int) -> c_int;
#[link_name = "_creat"]
fn creat(path: *c_char, mode: c_int) -> c_int;
unsafe fn creat(path: *c_char, mode: c_int) -> c_int;
}
#[nolink]
@@ -1199,61 +1201,63 @@ pub mod posix88 {
use libc::types::os::arch::c99::intptr_t;
#[link_name = "_access"]
fn access(path: *c_char, amode: c_int) -> c_int;
unsafe fn access(path: *c_char, amode: c_int) -> c_int;
#[link_name = "_chdir"]
fn chdir(dir: *c_char) -> c_int;
unsafe fn chdir(dir: *c_char) -> c_int;
#[link_name = "_close"]
fn close(fd: c_int) -> c_int;
unsafe fn close(fd: c_int) -> c_int;
#[link_name = "_dup"]
fn dup(fd: c_int) -> c_int;
unsafe fn dup(fd: c_int) -> c_int;
#[link_name = "_dup2"]
fn dup2(src: c_int, dst: c_int) -> c_int;
unsafe fn dup2(src: c_int, dst: c_int) -> c_int;
#[link_name = "_execv"]
fn execv(prog: *c_char, argv: **c_char) -> intptr_t;
unsafe fn execv(prog: *c_char, argv: **c_char) -> intptr_t;
#[link_name = "_execve"]
fn execve(prog: *c_char, argv: **c_char,
unsafe fn execve(prog: *c_char, argv: **c_char,
envp: **c_char) -> c_int;
#[link_name = "_execvp"]
fn execvp(c: *c_char, argv: **c_char) -> c_int;
unsafe fn execvp(c: *c_char, argv: **c_char) -> c_int;
#[link_name = "_execvpe"]
fn execvpe(c: *c_char, argv: **c_char,
unsafe fn execvpe(c: *c_char, argv: **c_char,
envp: **c_char) -> c_int;
#[link_name = "_getcwd"]
fn getcwd(buf: *c_char, size: size_t) -> *c_char;
unsafe fn getcwd(buf: *c_char, size: size_t) -> *c_char;
#[link_name = "_getpid"]
fn getpid() -> c_int;
unsafe fn getpid() -> c_int;
#[link_name = "_isatty"]
fn isatty(fd: c_int) -> c_int;
unsafe fn isatty(fd: c_int) -> c_int;
#[link_name = "_lseek"]
fn lseek(fd: c_int, offset: c_long, origin: c_int) -> c_long;
unsafe fn lseek(fd: c_int, offset: c_long, origin: c_int)
-> c_long;
#[link_name = "_pipe"]
fn pipe(fds: *mut c_int, psize: c_uint,
unsafe fn pipe(fds: *mut c_int, psize: c_uint,
textmode: c_int) -> c_int;
#[link_name = "_read"]
fn read(fd: c_int, buf: *mut c_void, count: c_uint) -> c_int;
unsafe fn read(fd: c_int, buf: *mut c_void, count: c_uint)
-> c_int;
#[link_name = "_rmdir"]
fn rmdir(path: *c_char) -> c_int;
unsafe fn rmdir(path: *c_char) -> c_int;
#[link_name = "_unlink"]
fn unlink(c: *c_char) -> c_int;
unsafe fn unlink(c: *c_char) -> c_int;
#[link_name = "_write"]
fn write(fd: c_int, buf: *c_void, count: c_uint) -> c_int;
unsafe fn write(fd: c_int, buf: *c_void, count: c_uint) -> c_int;
}
}
@@ -1274,104 +1278,106 @@ pub mod posix88 {
#[nolink]
#[abi = "cdecl"]
pub extern mod stat_ {
fn chmod(path: *c_char, mode: mode_t) -> c_int;
fn fchmod(fd: c_int, mode: mode_t) -> c_int;
unsafe fn chmod(path: *c_char, mode: mode_t) -> c_int;
unsafe fn fchmod(fd: c_int, mode: mode_t) -> c_int;
#[cfg(target_os = "linux")]
#[cfg(target_os = "freebsd")]
fn fstat(fildes: c_int, buf: *mut stat) -> c_int;
unsafe fn fstat(fildes: c_int, buf: *mut stat) -> c_int;
#[cfg(target_os = "macos")]
#[link_name = "fstat64"]
fn fstat(fildes: c_int, buf: *mut stat) -> c_int;
unsafe fn fstat(fildes: c_int, buf: *mut stat) -> c_int;
fn mkdir(path: *c_char, mode: mode_t) -> c_int;
fn mkfifo(path: *c_char, mode: mode_t) -> c_int;
unsafe fn mkdir(path: *c_char, mode: mode_t) -> c_int;
unsafe fn mkfifo(path: *c_char, mode: mode_t) -> c_int;
#[cfg(target_os = "linux")]
#[cfg(target_os = "freebsd")]
fn stat(path: *c_char, buf: *mut stat) -> c_int;
unsafe fn stat(path: *c_char, buf: *mut stat) -> c_int;
#[cfg(target_os = "macos")]
#[link_name = "stat64"]
fn stat(path: *c_char, buf: *mut stat) -> c_int;
unsafe fn stat(path: *c_char, buf: *mut stat) -> c_int;
}
#[nolink]
#[abi = "cdecl"]
pub extern mod stdio {
fn popen(command: *c_char, mode: *c_char) -> *FILE;
fn pclose(stream: *FILE) -> c_int;
fn fdopen(fd: c_int, mode: *c_char) -> *FILE;
fn fileno(stream: *FILE) -> c_int;
unsafe fn popen(command: *c_char, mode: *c_char) -> *FILE;
unsafe fn pclose(stream: *FILE) -> c_int;
unsafe fn fdopen(fd: c_int, mode: *c_char) -> *FILE;
unsafe fn fileno(stream: *FILE) -> c_int;
}
#[nolink]
#[abi = "cdecl"]
pub extern mod fcntl {
fn open(path: *c_char, oflag: c_int, mode: c_int) -> c_int;
fn creat(path: *c_char, mode: mode_t) -> c_int;
fn fcntl(fd: c_int, cmd: c_int) -> c_int;
unsafe fn open(path: *c_char, oflag: c_int, mode: c_int) -> c_int;
unsafe fn creat(path: *c_char, mode: mode_t) -> c_int;
unsafe fn fcntl(fd: c_int, cmd: c_int) -> c_int;
}
#[nolink]
#[abi = "cdecl"]
pub extern mod dirent {
fn opendir(dirname: *c_char) -> *DIR;
fn closedir(dirp: *DIR) -> c_int;
fn readdir(dirp: *DIR) -> *dirent_t;
fn rewinddir(dirp: *DIR);
fn seekdir(dirp: *DIR, loc: c_long);
fn telldir(dirp: *DIR) -> c_long;
unsafe fn opendir(dirname: *c_char) -> *DIR;
unsafe fn closedir(dirp: *DIR) -> c_int;
unsafe fn readdir(dirp: *DIR) -> *dirent_t;
unsafe fn rewinddir(dirp: *DIR);
unsafe fn seekdir(dirp: *DIR, loc: c_long);
unsafe fn telldir(dirp: *DIR) -> c_long;
}
#[nolink]
#[abi = "cdecl"]
pub extern mod unistd {
fn access(path: *c_char, amode: c_int) -> c_int;
fn alarm(seconds: c_uint) -> c_uint;
fn chdir(dir: *c_char) -> c_int;
fn chown(path: *c_char, uid: uid_t, gid: gid_t) -> c_int;
fn close(fd: c_int) -> c_int;
fn dup(fd: c_int) -> c_int;
fn dup2(src: c_int, dst: c_int) -> c_int;
fn execv(prog: *c_char, argv: **c_char) -> c_int;
fn execve(prog: *c_char, argv: **c_char,
envp: **c_char) -> c_int;
fn execvp(c: *c_char, argv: **c_char) -> c_int;
fn fork() -> pid_t;
fn fpathconf(filedes: c_int, name: c_int) -> c_long;
fn getcwd(buf: *c_char, size: size_t) -> *c_char;
fn getegid() -> gid_t;
fn geteuid() -> uid_t;
fn getgid() -> gid_t ;
fn getgroups(ngroups_max: c_int, groups: *mut gid_t) -> c_int;
fn getlogin() -> *c_char;
fn getopt(argc: c_int, argv: **c_char,
optstr: *c_char) -> c_int;
fn getpgrp() -> pid_t;
fn getpid() -> pid_t;
fn getppid() -> pid_t;
fn getuid() -> uid_t;
fn isatty(fd: c_int) -> c_int;
fn link(src: *c_char, dst: *c_char) -> c_int;
fn lseek(fd: c_int, offset: off_t, whence: c_int) -> off_t;
fn pathconf(path: *c_char, name: c_int) -> c_long;
fn pause() -> c_int;
fn pipe(fds: *mut c_int) -> c_int;
fn read(fd: c_int, buf: *mut c_void,
unsafe fn access(path: *c_char, amode: c_int) -> c_int;
unsafe fn alarm(seconds: c_uint) -> c_uint;
unsafe fn chdir(dir: *c_char) -> c_int;
unsafe fn chown(path: *c_char, uid: uid_t, gid: gid_t) -> c_int;
unsafe fn close(fd: c_int) -> c_int;
unsafe fn dup(fd: c_int) -> c_int;
unsafe fn dup2(src: c_int, dst: c_int) -> c_int;
unsafe fn execv(prog: *c_char, argv: **c_char) -> c_int;
unsafe fn execve(prog: *c_char, argv: **c_char, envp: **c_char)
-> c_int;
unsafe fn execvp(c: *c_char, argv: **c_char) -> c_int;
unsafe fn fork() -> pid_t;
unsafe fn fpathconf(filedes: c_int, name: c_int) -> c_long;
unsafe fn getcwd(buf: *c_char, size: size_t) -> *c_char;
unsafe fn getegid() -> gid_t;
unsafe fn geteuid() -> uid_t;
unsafe fn getgid() -> gid_t ;
unsafe fn getgroups(ngroups_max: c_int, groups: *mut gid_t)
-> c_int;
unsafe fn getlogin() -> *c_char;
unsafe fn getopt(argc: c_int, argv: **c_char, optstr: *c_char)
-> c_int;
unsafe fn getpgrp() -> pid_t;
unsafe fn getpid() -> pid_t;
unsafe fn getppid() -> pid_t;
unsafe fn getuid() -> uid_t;
unsafe fn isatty(fd: c_int) -> c_int;
unsafe fn link(src: *c_char, dst: *c_char) -> c_int;
unsafe fn lseek(fd: c_int, offset: off_t, whence: c_int) -> off_t;
unsafe fn pathconf(path: *c_char, name: c_int) -> c_long;
unsafe fn pause() -> c_int;
unsafe fn pipe(fds: *mut c_int) -> c_int;
unsafe fn read(fd: c_int, buf: *mut c_void,
count: size_t) -> ssize_t;
fn rmdir(path: *c_char) -> c_int;
fn setgid(gid: gid_t) -> c_int;
fn setpgid(pid: pid_t, pgid: pid_t) -> c_int;
fn setsid() -> pid_t;
fn setuid(uid: uid_t) -> c_int;
fn sleep(secs: c_uint) -> c_uint;
fn sysconf(name: c_int) -> c_long;
fn tcgetpgrp(fd: c_int) -> pid_t;
fn ttyname(fd: c_int) -> *c_char;
fn unlink(c: *c_char) -> c_int;
fn write(fd: c_int, buf: *c_void, count: size_t) -> ssize_t;
unsafe fn rmdir(path: *c_char) -> c_int;
unsafe fn setgid(gid: gid_t) -> c_int;
unsafe fn setpgid(pid: pid_t, pgid: pid_t) -> c_int;
unsafe fn setsid() -> pid_t;
unsafe fn setuid(uid: uid_t) -> c_int;
unsafe fn sleep(secs: c_uint) -> c_uint;
unsafe fn sysconf(name: c_int) -> c_long;
unsafe fn tcgetpgrp(fd: c_int) -> pid_t;
unsafe fn ttyname(fd: c_int) -> *c_char;
unsafe fn unlink(c: *c_char) -> c_int;
unsafe fn write(fd: c_int, buf: *c_void, count: size_t)
-> ssize_t;
}
}
@@ -1388,36 +1394,36 @@ pub mod posix01 {
pub extern mod stat_ {
#[cfg(target_os = "linux")]
#[cfg(target_os = "freebsd")]
fn lstat(path: *c_char, buf: *mut stat) -> c_int;
unsafe fn lstat(path: *c_char, buf: *mut stat) -> c_int;
#[cfg(target_os = "macos")]
#[link_name = "lstat64"]
fn lstat(path: *c_char, buf: *mut stat) -> c_int;
unsafe fn lstat(path: *c_char, buf: *mut stat) -> c_int;
}
#[nolink]
#[abi = "cdecl"]
pub extern mod unistd {
fn readlink(path: *c_char, buf: *mut c_char,
unsafe fn readlink(path: *c_char, buf: *mut c_char,
bufsz: size_t) -> ssize_t;
fn fsync(fd: c_int) -> c_int;
unsafe fn fsync(fd: c_int) -> c_int;
#[cfg(target_os = "linux")]
fn fdatasync(fd: c_int) -> c_int;
unsafe fn fdatasync(fd: c_int) -> c_int;
fn setenv(name: *c_char, val: *c_char,
unsafe fn setenv(name: *c_char, val: *c_char,
overwrite: c_int) -> c_int;
fn unsetenv(name: *c_char) -> c_int;
fn putenv(string: *c_char) -> c_int;
unsafe fn unsetenv(name: *c_char) -> c_int;
unsafe fn putenv(string: *c_char) -> c_int;
fn symlink(path1: *c_char, path2: *c_char) -> c_int;
unsafe fn symlink(path1: *c_char, path2: *c_char) -> c_int;
}
#[nolink]
#[abi = "cdecl"]
pub extern mod wait {
fn waitpid(pid: pid_t, status: *mut c_int,
unsafe fn waitpid(pid: pid_t, status: *mut c_int,
options: c_int) -> pid_t;
}
}
@@ -1453,15 +1459,15 @@ pub mod posix08 {
use libc::types::common::c95::{c_void};
use libc::types::os::arch::c95::{c_char, c_int, c_uint, size_t};
fn sysctl(name: *c_int, namelen: c_uint,
unsafe fn sysctl(name: *c_int, namelen: c_uint,
oldp: *mut c_void, oldlenp: *mut size_t,
newp: *c_void, newlen: size_t) -> c_int;
fn sysctlbyname(name: *c_char,
unsafe fn sysctlbyname(name: *c_char,
oldp: *mut c_void, oldlenp: *mut size_t,
newp: *c_void, newlen: size_t) -> c_int;
fn sysctlnametomib(name: *c_char, mibp: *mut c_int,
unsafe fn sysctlnametomib(name: *c_char, mibp: *mut c_int,
sizep: *mut size_t) -> c_int;
}
@@ -1477,7 +1483,7 @@ pub mod bsd44 {
pub extern mod extra {
use libc::types::os::arch::c95::{c_char, c_int};
fn _NSGetExecutablePath(buf: *mut c_char,
unsafe fn _NSGetExecutablePath(buf: *mut c_char,
bufsize: *mut u32) -> c_int;
}
@@ -1498,32 +1504,32 @@ pub mod extra {
#[abi = "stdcall"]
pub extern mod kernel32 {
fn GetEnvironmentVariableW(n: LPCWSTR,
unsafe fn GetEnvironmentVariableW(n: LPCWSTR,
v: LPWSTR,
nsize: DWORD) -> DWORD;
fn SetEnvironmentVariableW(n: LPCWSTR, v: LPCWSTR) -> BOOL;
unsafe fn SetEnvironmentVariableW(n: LPCWSTR, v: LPCWSTR) -> BOOL;
fn GetModuleFileNameW(hModule: HMODULE,
unsafe fn GetModuleFileNameW(hModule: HMODULE,
lpFilename: LPWSTR,
nSize: DWORD) -> DWORD;
fn CreateDirectoryW(lpPathName: LPCWSTR,
unsafe fn CreateDirectoryW(lpPathName: LPCWSTR,
lpSecurityAttributes:
LPSECURITY_ATTRIBUTES) -> BOOL;
fn CopyFileW(lpExistingFileName: LPCWSTR,
unsafe fn CopyFileW(lpExistingFileName: LPCWSTR,
lpNewFileName: LPCWSTR,
bFailIfExists: BOOL) -> BOOL;
fn DeleteFileW(lpPathName: LPCWSTR) -> BOOL;
fn RemoveDirectoryW(lpPathName: LPCWSTR) -> BOOL;
fn SetCurrentDirectoryW(lpPathName: LPCWSTR) -> BOOL;
unsafe fn DeleteFileW(lpPathName: LPCWSTR) -> BOOL;
unsafe fn RemoveDirectoryW(lpPathName: LPCWSTR) -> BOOL;
unsafe fn SetCurrentDirectoryW(lpPathName: LPCWSTR) -> BOOL;
fn GetLastError() -> DWORD;
unsafe fn GetLastError() -> DWORD;
}
#[abi = "cdecl"]
#[nolink]
pub extern mod msvcrt {
#[link_name = "_commit"]
pub fn commit(fd: c_int) -> c_int;
unsafe fn commit(fd: c_int) -> c_int;
}
}
}
+11 -5
View File
@@ -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)]
+92 -75
View File
@@ -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);
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();
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);
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);
}
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"]
+234 -166
View File
@@ -47,27 +47,35 @@
use uint;
use vec;
pub use libc::{close, fclose};
pub use libc::fclose;
pub use os::consts::*;
// FIXME: move these to str perhaps? #2620
pub fn close(fd: c_int) -> c_int {
unsafe {
libc::close(fd)
}
}
extern mod rustrt {
fn rust_get_argc() -> c_int;
fn rust_get_argv() -> **c_char;
fn rust_getcwd() -> ~str;
fn rust_path_is_dir(path: *libc::c_char) -> c_int;
fn rust_path_exists(path: *libc::c_char) -> c_int;
fn rust_list_files2(&&path: ~str) -> ~[~str];
fn rust_process_wait(handle: c_int) -> c_int;
fn last_os_error() -> ~str;
fn rust_set_exit_status(code: libc::intptr_t);
unsafe fn rust_get_argc() -> c_int;
unsafe fn rust_get_argv() -> **c_char;
unsafe fn rust_getcwd() -> ~str;
unsafe fn rust_path_is_dir(path: *libc::c_char) -> c_int;
unsafe fn rust_path_exists(path: *libc::c_char) -> c_int;
unsafe fn rust_list_files2(&&path: ~str) -> ~[~str];
unsafe fn rust_process_wait(handle: c_int) -> c_int;
unsafe fn last_os_error() -> ~str;
unsafe fn rust_set_exit_status(code: libc::intptr_t);
}
pub const tmpbuf_sz : uint = 1000u;
pub fn getcwd() -> Path {
Path(rustrt::rust_getcwd())
unsafe {
Path(rustrt::rust_getcwd())
}
}
pub fn as_c_charp<T>(s: &str, f: fn(*c_char) -> T) -> T {
@@ -152,7 +160,7 @@ mod global_env {
use task;
extern mod rustrt {
fn rust_global_env_chan_ptr() -> *libc::uintptr_t;
unsafe fn rust_global_env_chan_ptr() -> *libc::uintptr_t;
}
enum Msg {
@@ -186,8 +194,8 @@ pub fn env() -> ~[(~str,~str)] {
}
fn get_global_env_chan() -> oldcomm::Chan<Msg> {
let global_ptr = rustrt::rust_global_env_chan_ptr();
unsafe {
let global_ptr = rustrt::rust_global_env_chan_ptr();
private::chan_from_global_ptr(global_ptr, || {
// FIXME (#2621): This would be a good place to use a very
// small foreign stack
@@ -227,23 +235,25 @@ mod impl_ {
use vec;
extern mod rustrt {
fn rust_env_pairs() -> ~[~str];
unsafe fn rust_env_pairs() -> ~[~str];
}
pub fn env() -> ~[(~str,~str)] {
let mut pairs = ~[];
for vec::each(rustrt::rust_env_pairs()) |p| {
let vs = str::splitn_char(*p, '=', 1u);
assert vec::len(vs) == 2u;
pairs.push((copy vs[0], copy vs[1]));
unsafe {
let mut pairs = ~[];
for vec::each(rustrt::rust_env_pairs()) |p| {
let vs = str::splitn_char(*p, '=', 1u);
assert vec::len(vs) == 2u;
pairs.push((copy vs[0], copy vs[1]));
}
move pairs
}
move pairs
}
#[cfg(unix)]
pub fn getenv(n: &str) -> Option<~str> {
unsafe {
let s = str::as_c_str(n, libc::getenv);
let s = str::as_c_str(n, |s| libc::getenv(s));
return if ptr::null::<u8>() == cast::reinterpret_cast(&s) {
option::None::<~str>
} else {
@@ -255,10 +265,12 @@ pub fn getenv(n: &str) -> Option<~str> {
#[cfg(windows)]
pub fn getenv(n: &str) -> Option<~str> {
use os::win32::{as_utf16_p, fill_utf16_buf_and_decode};
do as_utf16_p(n) |u| {
do fill_utf16_buf_and_decode() |buf, sz| {
libc::GetEnvironmentVariableW(u, buf, sz)
unsafe {
use os::win32::{as_utf16_p, fill_utf16_buf_and_decode};
do as_utf16_p(n) |u| {
do fill_utf16_buf_and_decode() |buf, sz| {
libc::GetEnvironmentVariableW(u, buf, sz)
}
}
}
}
@@ -266,9 +278,11 @@ pub fn getenv(n: &str) -> Option<~str> {
#[cfg(unix)]
pub fn setenv(n: &str, v: &str) {
do str::as_c_str(n) |nbuf| {
do str::as_c_str(v) |vbuf| {
libc::funcs::posix01::unistd::setenv(nbuf, vbuf, 1i32);
unsafe {
do str::as_c_str(n) |nbuf| {
do str::as_c_str(v) |vbuf| {
libc::funcs::posix01::unistd::setenv(nbuf, vbuf, 1);
}
}
}
}
@@ -276,10 +290,12 @@ pub fn setenv(n: &str, v: &str) {
#[cfg(windows)]
pub fn setenv(n: &str, v: &str) {
use os::win32::as_utf16_p;
do as_utf16_p(n) |nbuf| {
do as_utf16_p(v) |vbuf| {
libc::SetEnvironmentVariableW(nbuf, vbuf);
unsafe {
use os::win32::as_utf16_p;
do as_utf16_p(n) |nbuf| {
do as_utf16_p(v) |vbuf| {
libc::SetEnvironmentVariableW(nbuf, vbuf);
}
}
}
}
@@ -288,9 +304,11 @@ pub fn setenv(n: &str, v: &str) {
}
pub fn fdopen(fd: c_int) -> *FILE {
return do as_c_charp("r") |modebuf| {
libc::fdopen(fd, modebuf)
};
unsafe {
return do as_c_charp("r") |modebuf| {
libc::fdopen(fd, modebuf)
};
}
}
@@ -314,74 +332,89 @@ pub fn fsync_fd(fd: c_int, level: io::fsync::Level) -> c_int {
#[cfg(target_os = "macos")]
pub fn fsync_fd(fd: c_int, level: io::fsync::Level) -> c_int {
use libc::consts::os::extra::*;
use libc::funcs::posix88::fcntl::*;
use libc::funcs::posix01::unistd::*;
match level {
io::fsync::FSync => return fsync(fd),
_ => {
// According to man fnctl, the ok retval is only specified to be !=-1
if (fcntl(F_FULLFSYNC as c_int, fd) == -1 as c_int)
{ return -1 as c_int; }
else
{ return 0 as c_int; }
}
unsafe {
use libc::consts::os::extra::*;
use libc::funcs::posix88::fcntl::*;
use libc::funcs::posix01::unistd::*;
match level {
io::fsync::FSync => return fsync(fd),
_ => {
// According to man fnctl, the ok retval is only specified to be
// !=-1
if (fcntl(F_FULLFSYNC as c_int, fd) == -1 as c_int)
{ return -1 as c_int; }
else
{ return 0 as c_int; }
}
}
}
}
#[cfg(target_os = "freebsd")]
pub fn fsync_fd(fd: c_int, _l: io::fsync::Level) -> c_int {
use libc::funcs::posix01::unistd::*;
return fsync(fd);
unsafe {
use libc::funcs::posix01::unistd::*;
return fsync(fd);
}
}
#[cfg(windows)]
pub fn waitpid(pid: pid_t) -> c_int {
return rustrt::rust_process_wait(pid);
unsafe {
return rustrt::rust_process_wait(pid);
}
}
#[cfg(unix)]
pub fn waitpid(pid: pid_t) -> c_int {
use libc::funcs::posix01::wait::*;
let status = 0 as c_int;
unsafe {
use libc::funcs::posix01::wait::*;
let status = 0 as c_int;
assert (waitpid(pid, ptr::mut_addr_of(&status),
0 as c_int) != (-1 as c_int));
return status;
assert (waitpid(pid, ptr::mut_addr_of(&status),
0 as c_int) != (-1 as c_int));
return status;
}
}
#[cfg(unix)]
pub fn pipe() -> {in: c_int, out: c_int} {
let fds = {mut in: 0 as c_int,
mut out: 0 as c_int };
assert (libc::pipe(ptr::mut_addr_of(&(fds.in))) == (0 as c_int));
return {in: fds.in, out: fds.out};
unsafe {
let fds = {mut in: 0 as c_int,
mut out: 0 as c_int };
assert (libc::pipe(ptr::mut_addr_of(&(fds.in))) == (0 as c_int));
return {in: fds.in, out: fds.out};
}
}
#[cfg(windows)]
pub fn pipe() -> {in: c_int, out: c_int} {
// Windows pipes work subtly differently than unix pipes, and their
// inheritance has to be handled in a different way that I do not fully
// understand. Here we explicitly make the pipe non-inheritable, which
// means to pass it to a subprocess they need to be duplicated first, as
// in rust_run_program.
let fds = { mut in: 0 as c_int,
mut out: 0 as c_int };
let res = libc::pipe(ptr::mut_addr_of(&(fds.in)),
1024 as c_uint,
(libc::O_BINARY | libc::O_NOINHERIT) as c_int);
assert (res == 0 as c_int);
assert (fds.in != -1 as c_int && fds.in != 0 as c_int);
assert (fds.out != -1 as c_int && fds.in != 0 as c_int);
return {in: fds.in, out: fds.out};
unsafe {
// Windows pipes work subtly differently than unix pipes, and their
// inheritance has to be handled in a different way that I do not
// fully understand. Here we explicitly make the pipe non-inheritable,
// which means to pass it to a subprocess they need to be duplicated
// first, as in rust_run_program.
let fds = { mut in: 0 as c_int,
mut out: 0 as c_int };
let res = libc::pipe(ptr::mut_addr_of(&(fds.in)),
1024 as c_uint,
(libc::O_BINARY | libc::O_NOINHERIT) as c_int);
assert (res == 0 as c_int);
assert (fds.in != -1 as c_int && fds.in != 0 as c_int);
assert (fds.out != -1 as c_int && fds.in != 0 as c_int);
return {in: fds.in, out: fds.out};
}
}
fn dup2(src: c_int, dst: c_int) -> c_int {
libc::dup2(src, dst)
unsafe {
libc::dup2(src, dst)
}
}
@@ -411,27 +444,33 @@ fn load_self() -> Option<~str> {
#[cfg(target_os = "linux")]
fn load_self() -> Option<~str> {
use libc::funcs::posix01::unistd::readlink;
do fill_charp_buf() |buf, sz| {
do as_c_charp("/proc/self/exe") |proc_self_buf| {
readlink(proc_self_buf, buf, sz) != (-1 as ssize_t)
unsafe {
use libc::funcs::posix01::unistd::readlink;
do fill_charp_buf() |buf, sz| {
do as_c_charp("/proc/self/exe") |proc_self_buf| {
readlink(proc_self_buf, buf, sz) != (-1 as ssize_t)
}
}
}
}
#[cfg(target_os = "macos")]
fn load_self() -> Option<~str> {
do fill_charp_buf() |buf, sz| {
libc::funcs::extra::_NSGetExecutablePath(
buf, ptr::mut_addr_of(&(sz as u32))) == (0 as c_int)
unsafe {
do fill_charp_buf() |buf, sz| {
libc::funcs::extra::_NSGetExecutablePath(
buf, ptr::mut_addr_of(&(sz as u32))) == (0 as c_int)
}
}
}
#[cfg(windows)]
fn load_self() -> Option<~str> {
use os::win32::fill_utf16_buf_and_decode;
do fill_utf16_buf_and_decode() |buf, sz| {
libc::GetModuleFileNameW(0u as libc::DWORD, buf, sz)
unsafe {
use os::win32::fill_utf16_buf_and_decode;
do fill_utf16_buf_and_decode() |buf, sz| {
libc::GetModuleFileNameW(0u as libc::DWORD, buf, sz)
}
}
}
@@ -555,15 +594,19 @@ fn walk_dir_(p: &Path, f: fn(&Path) -> bool) -> bool {
/// Indicates whether a path represents a directory
pub fn path_is_dir(p: &Path) -> bool {
do str::as_c_str(p.to_str()) |buf| {
rustrt::rust_path_is_dir(buf) != 0 as c_int
unsafe {
do str::as_c_str(p.to_str()) |buf| {
rustrt::rust_path_is_dir(buf) != 0 as c_int
}
}
}
/// Indicates whether a path exists
pub fn path_exists(p: &Path) -> bool {
do str::as_c_str(p.to_str()) |buf| {
rustrt::rust_path_exists(buf) != 0 as c_int
unsafe {
do str::as_c_str(p.to_str()) |buf| {
rustrt::rust_path_exists(buf) != 0 as c_int
}
}
}
@@ -592,20 +635,24 @@ pub fn make_dir(p: &Path, mode: c_int) -> bool {
#[cfg(windows)]
fn mkdir(p: &Path, _mode: c_int) -> bool {
use os::win32::as_utf16_p;
// FIXME: turn mode into something useful? #2623
do as_utf16_p(p.to_str()) |buf| {
libc::CreateDirectoryW(buf, unsafe {
cast::reinterpret_cast(&0)
})
!= (0 as libc::BOOL)
unsafe {
use os::win32::as_utf16_p;
// FIXME: turn mode into something useful? #2623
do as_utf16_p(p.to_str()) |buf| {
libc::CreateDirectoryW(buf, unsafe {
cast::reinterpret_cast(&0)
})
!= (0 as libc::BOOL)
}
}
}
#[cfg(unix)]
fn mkdir(p: &Path, mode: c_int) -> bool {
do as_c_charp(p.to_str()) |c| {
libc::mkdir(c, mode as mode_t) == (0 as c_int)
unsafe {
do as_c_charp(p.to_str()) |c| {
libc::mkdir(c, mode as mode_t) == (0 as c_int)
}
}
}
}
@@ -613,15 +660,16 @@ fn mkdir(p: &Path, mode: c_int) -> bool {
/// Lists the contents of a directory
#[allow(non_implicitly_copyable_typarams)]
pub fn list_dir(p: &Path) -> ~[~str] {
unsafe {
#[cfg(unix)]
fn star(p: &Path) -> Path { copy *p }
#[cfg(unix)]
fn star(p: &Path) -> Path { copy *p }
#[cfg(windows)]
fn star(p: &Path) -> Path { p.push("*") }
#[cfg(windows)]
fn star(p: &Path) -> Path { p.push("*") }
do rustrt::rust_list_files2(star(p).to_str()).filtered |filename| {
*filename != ~"." && *filename != ~".."
do rustrt::rust_list_files2(star(p).to_str()).filtered |filename| {
*filename != ~"." && *filename != ~".."
}
}
}
@@ -640,17 +688,21 @@ pub fn remove_dir(p: &Path) -> bool {
#[cfg(windows)]
fn rmdir(p: &Path) -> bool {
use os::win32::as_utf16_p;
return do as_utf16_p(p.to_str()) |buf| {
libc::RemoveDirectoryW(buf) != (0 as libc::BOOL)
};
unsafe {
use os::win32::as_utf16_p;
return do as_utf16_p(p.to_str()) |buf| {
libc::RemoveDirectoryW(buf) != (0 as libc::BOOL)
};
}
}
#[cfg(unix)]
fn rmdir(p: &Path) -> bool {
return do as_c_charp(p.to_str()) |buf| {
libc::rmdir(buf) == (0 as c_int)
};
unsafe {
return do as_c_charp(p.to_str()) |buf| {
libc::rmdir(buf) == (0 as c_int)
};
}
}
}
@@ -659,17 +711,21 @@ pub fn change_dir(p: &Path) -> bool {
#[cfg(windows)]
fn chdir(p: &Path) -> bool {
use os::win32::as_utf16_p;
return do as_utf16_p(p.to_str()) |buf| {
libc::SetCurrentDirectoryW(buf) != (0 as libc::BOOL)
};
unsafe {
use os::win32::as_utf16_p;
return do as_utf16_p(p.to_str()) |buf| {
libc::SetCurrentDirectoryW(buf) != (0 as libc::BOOL)
};
}
}
#[cfg(unix)]
fn chdir(p: &Path) -> bool {
return do as_c_charp(p.to_str()) |buf| {
libc::chdir(buf) == (0 as c_int)
};
unsafe {
return do as_c_charp(p.to_str()) |buf| {
libc::chdir(buf) == (0 as c_int)
};
}
}
}
@@ -679,57 +735,61 @@ pub fn copy_file(from: &Path, to: &Path) -> bool {
#[cfg(windows)]
fn do_copy_file(from: &Path, to: &Path) -> bool {
use os::win32::as_utf16_p;
return do as_utf16_p(from.to_str()) |fromp| {
do as_utf16_p(to.to_str()) |top| {
libc::CopyFileW(fromp, top, (0 as libc::BOOL)) !=
(0 as libc::BOOL)
unsafe {
use os::win32::as_utf16_p;
return do as_utf16_p(from.to_str()) |fromp| {
do as_utf16_p(to.to_str()) |top| {
libc::CopyFileW(fromp, top, (0 as libc::BOOL)) !=
(0 as libc::BOOL)
}
}
}
}
#[cfg(unix)]
fn do_copy_file(from: &Path, to: &Path) -> bool {
let istream = do as_c_charp(from.to_str()) |fromp| {
do as_c_charp("rb") |modebuf| {
libc::fopen(fromp, modebuf)
unsafe {
let istream = do as_c_charp(from.to_str()) |fromp| {
do as_c_charp("rb") |modebuf| {
libc::fopen(fromp, modebuf)
}
};
if istream as uint == 0u {
return false;
}
};
if istream as uint == 0u {
return false;
}
let ostream = do as_c_charp(to.to_str()) |top| {
do as_c_charp("w+b") |modebuf| {
libc::fopen(top, modebuf)
let ostream = do as_c_charp(to.to_str()) |top| {
do as_c_charp("w+b") |modebuf| {
libc::fopen(top, modebuf)
}
};
if ostream as uint == 0u {
fclose(istream);
return false;
}
};
if ostream as uint == 0u {
fclose(istream);
return false;
}
let bufsize = 8192u;
let mut buf = vec::with_capacity::<u8>(bufsize);
let mut done = false;
let mut ok = true;
while !done {
do vec::as_mut_buf(buf) |b, _sz| {
let nread = libc::fread(b as *mut c_void, 1u as size_t,
bufsize as size_t,
istream);
if nread > 0 as size_t {
if libc::fwrite(b as *c_void, 1u as size_t, nread,
ostream) != nread {
ok = false;
let bufsize = 8192u;
let mut buf = vec::with_capacity::<u8>(bufsize);
let mut done = false;
let mut ok = true;
while !done {
do vec::as_mut_buf(buf) |b, _sz| {
let nread = libc::fread(b as *mut c_void, 1u as size_t,
bufsize as size_t,
istream);
if nread > 0 as size_t {
if libc::fwrite(b as *c_void, 1u as size_t, nread,
ostream) != nread {
ok = false;
done = true;
}
} else {
done = true;
}
} else {
done = true;
}
}
}
fclose(istream);
fclose(ostream);
return ok;
}
fclose(istream);
fclose(ostream);
return ok;
}
}
@@ -739,23 +799,29 @@ pub fn remove_file(p: &Path) -> bool {
#[cfg(windows)]
fn unlink(p: &Path) -> bool {
use os::win32::as_utf16_p;
return do as_utf16_p(p.to_str()) |buf| {
libc::DeleteFileW(buf) != (0 as libc::BOOL)
};
unsafe {
use os::win32::as_utf16_p;
return do as_utf16_p(p.to_str()) |buf| {
libc::DeleteFileW(buf) != (0 as libc::BOOL)
};
}
}
#[cfg(unix)]
fn unlink(p: &Path) -> bool {
return do as_c_charp(p.to_str()) |buf| {
libc::unlink(buf) == (0 as c_int)
};
unsafe {
return do as_c_charp(p.to_str()) |buf| {
libc::unlink(buf) == (0 as c_int)
};
}
}
}
/// Get a string representing the platform-dependent last error
pub fn last_os_error() -> ~str {
rustrt::last_os_error()
unsafe {
rustrt::last_os_error()
}
}
/**
@@ -767,7 +833,9 @@ pub fn last_os_error() -> ~str {
* ignored and the process exits with the default failure status
*/
pub fn set_exit_status(code: int) {
rustrt::rust_set_exit_status(code as libc::intptr_t);
unsafe {
rustrt::rust_set_exit_status(code as libc::intptr_t);
}
}
unsafe fn load_argc_and_argv(argc: c_int, argv: **c_char) -> ~[~str] {
+12 -8
View File
@@ -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 }
}
}
}
+58 -30
View File
@@ -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 {
+20 -11
View File
@@ -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 {
+12 -6
View File
@@ -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"]
+26 -12
View File
@@ -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
}
+11 -10
View File
@@ -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);
}
+146 -127
View File
@@ -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);
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;
unsafe {
if pid == -1 as pid_t { fail; }
libc::close(pipe_input.in);
libc::close(pipe_output.out);
libc::close(pipe_err.out);
}
}
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
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); }
}
}
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); }
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); }
}
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
+7 -3
View File
@@ -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"]
+1 -1
View File
@@ -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.
+6 -6
View File
@@ -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]
+3 -3
View File
@@ -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"]
+185 -170
View File
@@ -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,203 +198,210 @@ 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.
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.
// 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");
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 !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);
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);
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; }
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);
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);
if threshold != 0u {
llvm::LLVMPassManagerBuilderUseInlinerWithThreshold
(MPMB, threshold as c_uint);
}
llvm::LLVMPassManagerBuilderPopulateModulePassManager(
MPMB, pm.llpm);
llvm::LLVMPassManagerBuilderDispose(MPMB);
}
llvm::LLVMPassManagerBuilderPopulateModulePassManager(MPMB,
pm.llpm);
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
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
};
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();
}
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.
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
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
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)
})
});
}
// Clean up and return
llvm::LLVMDisposeModule(llmod);
if sess.time_llvm_passes() {
llvm::LLVMRustPrintPassTimings();
}
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.
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
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)
})
});
}
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(); }
}
}
+3 -1
View File
@@ -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");
+813 -598
View File
@@ -257,754 +257,930 @@ enum SectionIterator_opaque {}
extern mod llvm {
#[legacy_exports];
/* Create and destroy contexts. */
fn LLVMContextCreate() -> ContextRef;
fn LLVMGetGlobalContext() -> ContextRef;
fn LLVMContextDispose(C: ContextRef);
fn LLVMGetMDKindIDInContext(C: ContextRef, Name: *c_char, SLen: c_uint) ->
c_uint;
fn LLVMGetMDKindID(Name: *c_char, SLen: c_uint) -> c_uint;
unsafe fn LLVMContextCreate() -> ContextRef;
unsafe fn LLVMGetGlobalContext() -> ContextRef;
unsafe fn LLVMContextDispose(C: ContextRef);
unsafe fn LLVMGetMDKindIDInContext(C: ContextRef,
Name: *c_char,
SLen: c_uint)
-> c_uint;
unsafe fn LLVMGetMDKindID(Name: *c_char, SLen: c_uint) -> c_uint;
/* Create and destroy modules. */
fn LLVMModuleCreateWithNameInContext(ModuleID: *c_char, C: ContextRef) ->
ModuleRef;
fn LLVMDisposeModule(M: ModuleRef);
unsafe fn LLVMModuleCreateWithNameInContext(ModuleID: *c_char,
C: ContextRef)
-> ModuleRef;
unsafe fn LLVMDisposeModule(M: ModuleRef);
/** Data layout. See Module::getDataLayout. */
fn LLVMGetDataLayout(M: ModuleRef) -> *c_char;
fn LLVMSetDataLayout(M: ModuleRef, Triple: *c_char);
unsafe fn LLVMGetDataLayout(M: ModuleRef) -> *c_char;
unsafe fn LLVMSetDataLayout(M: ModuleRef, Triple: *c_char);
/** Target triple. See Module::getTargetTriple. */
fn LLVMGetTarget(M: ModuleRef) -> *c_char;
fn LLVMSetTarget(M: ModuleRef, Triple: *c_char);
unsafe fn LLVMGetTarget(M: ModuleRef) -> *c_char;
unsafe fn LLVMSetTarget(M: ModuleRef, Triple: *c_char);
/** See Module::dump. */
fn LLVMDumpModule(M: ModuleRef);
unsafe fn LLVMDumpModule(M: ModuleRef);
/** See Module::setModuleInlineAsm. */
fn LLVMSetModuleInlineAsm(M: ModuleRef, Asm: *c_char);
unsafe fn LLVMSetModuleInlineAsm(M: ModuleRef, Asm: *c_char);
/** See llvm::LLVMTypeKind::getTypeID. */
fn LLVMGetTypeKind(Ty: TypeRef) -> TypeKind;
unsafe fn LLVMGetTypeKind(Ty: TypeRef) -> TypeKind;
/** See llvm::LLVMType::getContext. */
fn LLVMGetTypeContext(Ty: TypeRef) -> ContextRef;
unsafe fn LLVMGetTypeContext(Ty: TypeRef) -> ContextRef;
/* Operations on integer types */
fn LLVMInt1TypeInContext(C: ContextRef) -> TypeRef;
fn LLVMInt8TypeInContext(C: ContextRef) -> TypeRef;
fn LLVMInt16TypeInContext(C: ContextRef) -> TypeRef;
fn LLVMInt32TypeInContext(C: ContextRef) -> TypeRef;
fn LLVMInt64TypeInContext(C: ContextRef) -> TypeRef;
fn LLVMIntTypeInContext(C: ContextRef, NumBits: c_uint) -> TypeRef;
unsafe fn LLVMInt1TypeInContext(C: ContextRef) -> TypeRef;
unsafe fn LLVMInt8TypeInContext(C: ContextRef) -> TypeRef;
unsafe fn LLVMInt16TypeInContext(C: ContextRef) -> TypeRef;
unsafe fn LLVMInt32TypeInContext(C: ContextRef) -> TypeRef;
unsafe fn LLVMInt64TypeInContext(C: ContextRef) -> TypeRef;
unsafe fn LLVMIntTypeInContext(C: ContextRef, NumBits: c_uint) -> TypeRef;
fn LLVMInt1Type() -> TypeRef;
fn LLVMInt8Type() -> TypeRef;
fn LLVMInt16Type() -> TypeRef;
fn LLVMInt32Type() -> TypeRef;
fn LLVMInt64Type() -> TypeRef;
fn LLVMIntType(NumBits: c_uint) -> TypeRef;
fn LLVMGetIntTypeWidth(IntegerTy: TypeRef) -> c_uint;
unsafe fn LLVMInt1Type() -> TypeRef;
unsafe fn LLVMInt8Type() -> TypeRef;
unsafe fn LLVMInt16Type() -> TypeRef;
unsafe fn LLVMInt32Type() -> TypeRef;
unsafe fn LLVMInt64Type() -> TypeRef;
unsafe fn LLVMIntType(NumBits: c_uint) -> TypeRef;
unsafe fn LLVMGetIntTypeWidth(IntegerTy: TypeRef) -> c_uint;
/* Operations on real types */
fn LLVMFloatTypeInContext(C: ContextRef) -> TypeRef;
fn LLVMDoubleTypeInContext(C: ContextRef) -> TypeRef;
fn LLVMX86FP80TypeInContext(C: ContextRef) -> TypeRef;
fn LLVMFP128TypeInContext(C: ContextRef) -> TypeRef;
fn LLVMPPCFP128TypeInContext(C: ContextRef) -> TypeRef;
unsafe fn LLVMFloatTypeInContext(C: ContextRef) -> TypeRef;
unsafe fn LLVMDoubleTypeInContext(C: ContextRef) -> TypeRef;
unsafe fn LLVMX86FP80TypeInContext(C: ContextRef) -> TypeRef;
unsafe fn LLVMFP128TypeInContext(C: ContextRef) -> TypeRef;
unsafe fn LLVMPPCFP128TypeInContext(C: ContextRef) -> TypeRef;
fn LLVMFloatType() -> TypeRef;
fn LLVMDoubleType() -> TypeRef;
fn LLVMX86FP80Type() -> TypeRef;
fn LLVMFP128Type() -> TypeRef;
fn LLVMPPCFP128Type() -> TypeRef;
unsafe fn LLVMFloatType() -> TypeRef;
unsafe fn LLVMDoubleType() -> TypeRef;
unsafe fn LLVMX86FP80Type() -> TypeRef;
unsafe fn LLVMFP128Type() -> TypeRef;
unsafe fn LLVMPPCFP128Type() -> TypeRef;
/* Operations on function types */
fn LLVMFunctionType(ReturnType: TypeRef, ParamTypes: *TypeRef,
unsafe fn LLVMFunctionType(ReturnType: TypeRef, ParamTypes: *TypeRef,
ParamCount: c_uint, IsVarArg: Bool) -> TypeRef;
fn LLVMIsFunctionVarArg(FunctionTy: TypeRef) -> Bool;
fn LLVMGetReturnType(FunctionTy: TypeRef) -> TypeRef;
fn LLVMCountParamTypes(FunctionTy: TypeRef) -> c_uint;
fn LLVMGetParamTypes(FunctionTy: TypeRef, Dest: *TypeRef);
unsafe fn LLVMIsFunctionVarArg(FunctionTy: TypeRef) -> Bool;
unsafe fn LLVMGetReturnType(FunctionTy: TypeRef) -> TypeRef;
unsafe fn LLVMCountParamTypes(FunctionTy: TypeRef) -> c_uint;
unsafe fn LLVMGetParamTypes(FunctionTy: TypeRef, Dest: *TypeRef);
/* Operations on struct types */
fn LLVMStructTypeInContext(C: ContextRef, ElementTypes: *TypeRef,
unsafe fn LLVMStructTypeInContext(C: ContextRef, ElementTypes: *TypeRef,
ElementCount: c_uint,
Packed: Bool) -> TypeRef;
fn LLVMStructType(ElementTypes: *TypeRef, ElementCount: c_uint,
unsafe fn LLVMStructType(ElementTypes: *TypeRef, ElementCount: c_uint,
Packed: Bool) -> TypeRef;
fn LLVMCountStructElementTypes(StructTy: TypeRef) -> c_uint;
fn LLVMGetStructElementTypes(StructTy: TypeRef, Dest: *mut TypeRef);
fn LLVMIsPackedStruct(StructTy: TypeRef) -> Bool;
unsafe fn LLVMCountStructElementTypes(StructTy: TypeRef) -> c_uint;
unsafe fn LLVMGetStructElementTypes(StructTy: TypeRef,
Dest: *mut TypeRef);
unsafe fn LLVMIsPackedStruct(StructTy: TypeRef) -> Bool;
/* Operations on array, pointer, and vector types (sequence types) */
fn LLVMArrayType(ElementType: TypeRef,
unsafe fn LLVMArrayType(ElementType: TypeRef,
ElementCount: c_uint) -> TypeRef;
fn LLVMPointerType(ElementType: TypeRef,
unsafe fn LLVMPointerType(ElementType: TypeRef,
AddressSpace: c_uint) -> TypeRef;
fn LLVMVectorType(ElementType: TypeRef,
unsafe fn LLVMVectorType(ElementType: TypeRef,
ElementCount: c_uint) -> TypeRef;
fn LLVMGetElementType(Ty: TypeRef) -> TypeRef;
fn LLVMGetArrayLength(ArrayTy: TypeRef) -> c_uint;
fn LLVMGetPointerAddressSpace(PointerTy: TypeRef) -> c_uint;
fn LLVMGetVectorSize(VectorTy: TypeRef) -> c_uint;
unsafe fn LLVMGetElementType(Ty: TypeRef) -> TypeRef;
unsafe fn LLVMGetArrayLength(ArrayTy: TypeRef) -> c_uint;
unsafe fn LLVMGetPointerAddressSpace(PointerTy: TypeRef) -> c_uint;
unsafe fn LLVMGetVectorSize(VectorTy: TypeRef) -> c_uint;
/* Operations on other types */
fn LLVMVoidTypeInContext(C: ContextRef) -> TypeRef;
fn LLVMLabelTypeInContext(C: ContextRef) -> TypeRef;
fn LLVMMetadataTypeInContext(C: ContextRef) -> TypeRef;
unsafe fn LLVMVoidTypeInContext(C: ContextRef) -> TypeRef;
unsafe fn LLVMLabelTypeInContext(C: ContextRef) -> TypeRef;
unsafe fn LLVMMetadataTypeInContext(C: ContextRef) -> TypeRef;
fn LLVMVoidType() -> TypeRef;
fn LLVMLabelType() -> TypeRef;
fn LLVMMetadataType() -> TypeRef;
unsafe fn LLVMVoidType() -> TypeRef;
unsafe fn LLVMLabelType() -> TypeRef;
unsafe fn LLVMMetadataType() -> TypeRef;
/* Operations on all values */
fn LLVMTypeOf(Val: ValueRef) -> TypeRef;
fn LLVMGetValueName(Val: ValueRef) -> *c_char;
fn LLVMSetValueName(Val: ValueRef, Name: *c_char);
fn LLVMDumpValue(Val: ValueRef);
fn LLVMReplaceAllUsesWith(OldVal: ValueRef, NewVal: ValueRef);
fn LLVMHasMetadata(Val: ValueRef) -> c_int;
fn LLVMGetMetadata(Val: ValueRef, KindID: c_uint) -> ValueRef;
fn LLVMSetMetadata(Val: ValueRef, KindID: c_uint, Node: ValueRef);
unsafe fn LLVMTypeOf(Val: ValueRef) -> TypeRef;
unsafe fn LLVMGetValueName(Val: ValueRef) -> *c_char;
unsafe fn LLVMSetValueName(Val: ValueRef, Name: *c_char);
unsafe fn LLVMDumpValue(Val: ValueRef);
unsafe fn LLVMReplaceAllUsesWith(OldVal: ValueRef, NewVal: ValueRef);
unsafe fn LLVMHasMetadata(Val: ValueRef) -> c_int;
unsafe fn LLVMGetMetadata(Val: ValueRef, KindID: c_uint) -> ValueRef;
unsafe fn LLVMSetMetadata(Val: ValueRef, KindID: c_uint, Node: ValueRef);
/* Operations on Uses */
fn LLVMGetFirstUse(Val: ValueRef) -> UseRef;
fn LLVMGetNextUse(U: UseRef) -> UseRef;
fn LLVMGetUser(U: UseRef) -> ValueRef;
fn LLVMGetUsedValue(U: UseRef) -> ValueRef;
unsafe fn LLVMGetFirstUse(Val: ValueRef) -> UseRef;
unsafe fn LLVMGetNextUse(U: UseRef) -> UseRef;
unsafe fn LLVMGetUser(U: UseRef) -> ValueRef;
unsafe fn LLVMGetUsedValue(U: UseRef) -> ValueRef;
/* Operations on Users */
fn LLVMGetOperand(Val: ValueRef, Index: c_uint) -> ValueRef;
fn LLVMSetOperand(Val: ValueRef, Index: c_uint, Op: ValueRef);
unsafe fn LLVMGetOperand(Val: ValueRef, Index: c_uint) -> ValueRef;
unsafe fn LLVMSetOperand(Val: ValueRef, Index: c_uint, Op: ValueRef);
/* Operations on constants of any type */
fn LLVMConstNull(Ty: TypeRef) -> ValueRef;
unsafe fn LLVMConstNull(Ty: TypeRef) -> ValueRef;
/* all zeroes */
fn LLVMConstAllOnes(Ty: TypeRef) -> ValueRef;
unsafe fn LLVMConstAllOnes(Ty: TypeRef) -> ValueRef;
/* only for int/vector */
fn LLVMGetUndef(Ty: TypeRef) -> ValueRef;
fn LLVMIsConstant(Val: ValueRef) -> Bool;
fn LLVMIsNull(Val: ValueRef) -> Bool;
fn LLVMIsUndef(Val: ValueRef) -> Bool;
fn LLVMConstPointerNull(Ty: TypeRef) -> ValueRef;
unsafe fn LLVMGetUndef(Ty: TypeRef) -> ValueRef;
unsafe fn LLVMIsConstant(Val: ValueRef) -> Bool;
unsafe fn LLVMIsNull(Val: ValueRef) -> Bool;
unsafe fn LLVMIsUndef(Val: ValueRef) -> Bool;
unsafe fn LLVMConstPointerNull(Ty: TypeRef) -> ValueRef;
/* Operations on metadata */
fn LLVMMDStringInContext(C: ContextRef, Str: *c_char, SLen: c_uint) ->
ValueRef;
fn LLVMMDString(Str: *c_char, SLen: c_uint) -> ValueRef;
fn LLVMMDNodeInContext(C: ContextRef, Vals: *ValueRef, Count: c_uint) ->
ValueRef;
fn LLVMMDNode(Vals: *ValueRef, Count: c_uint) -> ValueRef;
fn LLVMAddNamedMetadataOperand(M: ModuleRef, Str: *c_char,
unsafe fn LLVMMDStringInContext(C: ContextRef,
Str: *c_char,
SLen: c_uint)
-> ValueRef;
unsafe fn LLVMMDString(Str: *c_char, SLen: c_uint) -> ValueRef;
unsafe fn LLVMMDNodeInContext(C: ContextRef,
Vals: *ValueRef,
Count: c_uint)
-> ValueRef;
unsafe fn LLVMMDNode(Vals: *ValueRef, Count: c_uint) -> ValueRef;
unsafe fn LLVMAddNamedMetadataOperand(M: ModuleRef, Str: *c_char,
Val: ValueRef);
/* Operations on scalar constants */
fn LLVMConstInt(IntTy: TypeRef, N: c_ulonglong, SignExtend: Bool) ->
ValueRef;
fn LLVMConstIntOfString(IntTy: TypeRef, Text: *c_char, Radix: u8) ->
ValueRef;
fn LLVMConstIntOfStringAndSize(IntTy: TypeRef, Text: *c_char,
unsafe fn LLVMConstInt(IntTy: TypeRef,
N: c_ulonglong,
SignExtend: Bool)
-> ValueRef;
unsafe fn LLVMConstIntOfString(IntTy: TypeRef,
Text: *c_char,
Radix: u8)
-> ValueRef;
unsafe fn LLVMConstIntOfStringAndSize(IntTy: TypeRef, Text: *c_char,
SLen: c_uint,
Radix: u8) -> ValueRef;
fn LLVMConstReal(RealTy: TypeRef, N: f64) -> ValueRef;
fn LLVMConstRealOfString(RealTy: TypeRef, Text: *c_char) -> ValueRef;
fn LLVMConstRealOfStringAndSize(RealTy: TypeRef, Text: *c_char,
unsafe fn LLVMConstReal(RealTy: TypeRef, N: f64) -> ValueRef;
unsafe fn LLVMConstRealOfString(RealTy: TypeRef,
Text: *c_char)
-> ValueRef;
unsafe fn LLVMConstRealOfStringAndSize(RealTy: TypeRef, Text: *c_char,
SLen: c_uint) -> ValueRef;
fn LLVMConstIntGetZExtValue(ConstantVal: ValueRef) -> c_ulonglong;
fn LLVMConstIntGetSExtValue(ConstantVal: ValueRef) -> c_longlong;
unsafe fn LLVMConstIntGetZExtValue(ConstantVal: ValueRef) -> c_ulonglong;
unsafe fn LLVMConstIntGetSExtValue(ConstantVal: ValueRef) -> c_longlong;
/* Operations on composite constants */
fn LLVMConstStringInContext(C: ContextRef, Str: *c_char, Length: c_uint,
DontNullTerminate: Bool) -> ValueRef;
fn LLVMConstStructInContext(C: ContextRef, ConstantVals: *ValueRef,
unsafe fn LLVMConstStringInContext(C: ContextRef,
Str: *c_char,
Length: c_uint,
DontNullTerminate: Bool)
-> ValueRef;
unsafe fn LLVMConstStructInContext(C: ContextRef, ConstantVals: *ValueRef,
Count: c_uint, Packed: Bool) -> ValueRef;
fn LLVMConstString(Str: *c_char, Length: c_uint,
unsafe fn LLVMConstString(Str: *c_char, Length: c_uint,
DontNullTerminate: Bool) -> ValueRef;
fn LLVMConstArray(ElementTy: TypeRef, ConstantVals: *ValueRef,
unsafe fn LLVMConstArray(ElementTy: TypeRef, ConstantVals: *ValueRef,
Length: c_uint) -> ValueRef;
fn LLVMConstStruct(ConstantVals: *ValueRef,
unsafe fn LLVMConstStruct(ConstantVals: *ValueRef,
Count: c_uint, Packed: Bool) -> ValueRef;
fn LLVMConstVector(ScalarConstantVals: *ValueRef,
unsafe fn LLVMConstVector(ScalarConstantVals: *ValueRef,
Size: c_uint) -> ValueRef;
/* Constant expressions */
fn LLVMAlignOf(Ty: TypeRef) -> ValueRef;
fn LLVMSizeOf(Ty: TypeRef) -> ValueRef;
fn LLVMConstNeg(ConstantVal: ValueRef) -> ValueRef;
fn LLVMConstNSWNeg(ConstantVal: ValueRef) -> ValueRef;
fn LLVMConstNUWNeg(ConstantVal: ValueRef) -> ValueRef;
fn LLVMConstFNeg(ConstantVal: ValueRef) -> ValueRef;
fn LLVMConstNot(ConstantVal: ValueRef) -> ValueRef;
fn LLVMConstAdd(LHSConstant: ValueRef, RHSConstant: ValueRef) -> ValueRef;
fn LLVMConstNSWAdd(LHSConstant: ValueRef, RHSConstant: ValueRef) ->
unsafe fn LLVMAlignOf(Ty: TypeRef) -> ValueRef;
unsafe fn LLVMSizeOf(Ty: TypeRef) -> ValueRef;
unsafe fn LLVMConstNeg(ConstantVal: ValueRef) -> ValueRef;
unsafe fn LLVMConstNSWNeg(ConstantVal: ValueRef) -> ValueRef;
unsafe fn LLVMConstNUWNeg(ConstantVal: ValueRef) -> ValueRef;
unsafe fn LLVMConstFNeg(ConstantVal: ValueRef) -> ValueRef;
unsafe fn LLVMConstNot(ConstantVal: ValueRef) -> ValueRef;
unsafe fn LLVMConstAdd(LHSConstant: ValueRef,
RHSConstant: ValueRef)
-> ValueRef;
unsafe fn LLVMConstNSWAdd(LHSConstant: ValueRef,
RHSConstant: ValueRef)
-> ValueRef;
unsafe fn LLVMConstNUWAdd(LHSConstant: ValueRef,
RHSConstant: ValueRef)
-> ValueRef;
unsafe fn LLVMConstFAdd(LHSConstant: ValueRef,
RHSConstant: ValueRef)
-> ValueRef;
unsafe fn LLVMConstSub(LHSConstant: ValueRef,
RHSConstant: ValueRef)
-> ValueRef;
unsafe fn LLVMConstNSWSub(LHSConstant: ValueRef,
RHSConstant: ValueRef)
-> ValueRef;
unsafe fn LLVMConstNUWSub(LHSConstant: ValueRef,
RHSConstant: ValueRef)
-> ValueRef;
unsafe fn LLVMConstFSub(LHSConstant: ValueRef, RHSConstant: ValueRef) ->
ValueRef;
fn LLVMConstNUWAdd(LHSConstant: ValueRef, RHSConstant: ValueRef) ->
unsafe fn LLVMConstMul(LHSConstant: ValueRef,
RHSConstant: ValueRef)
-> ValueRef;
unsafe fn LLVMConstNSWMul(LHSConstant: ValueRef,
RHSConstant: ValueRef)
-> ValueRef;
unsafe fn LLVMConstNUWMul(LHSConstant: ValueRef,
RHSConstant: ValueRef)
-> ValueRef;
unsafe fn LLVMConstFMul(LHSConstant: ValueRef,
RHSConstant: ValueRef)
-> ValueRef;
unsafe fn LLVMConstUDiv(LHSConstant: ValueRef,
RHSConstant: ValueRef)
-> ValueRef;
unsafe fn LLVMConstSDiv(LHSConstant: ValueRef,
RHSConstant: ValueRef)
-> ValueRef;
unsafe fn LLVMConstExactSDiv(LHSConstant: ValueRef,
RHSConstant: ValueRef)
-> ValueRef;
unsafe fn LLVMConstFDiv(LHSConstant: ValueRef,
RHSConstant: ValueRef)
-> ValueRef;
unsafe fn LLVMConstURem(LHSConstant: ValueRef,
RHSConstant: ValueRef)
-> ValueRef;
unsafe fn LLVMConstSRem(LHSConstant: ValueRef,
RHSConstant: ValueRef)
-> ValueRef;
unsafe fn LLVMConstFRem(LHSConstant: ValueRef,
RHSConstant: ValueRef)
-> ValueRef;
unsafe fn LLVMConstAnd(LHSConstant: ValueRef,
RHSConstant: ValueRef)
-> ValueRef;
unsafe fn LLVMConstOr(LHSConstant: ValueRef,
RHSConstant: ValueRef)
-> ValueRef;
unsafe fn LLVMConstXor(LHSConstant: ValueRef,
RHSConstant: ValueRef)
-> ValueRef;
unsafe fn LLVMConstShl(LHSConstant: ValueRef,
RHSConstant: ValueRef)
-> ValueRef;
unsafe fn LLVMConstLShr(LHSConstant: ValueRef, RHSConstant: ValueRef) ->
ValueRef;
fn LLVMConstFAdd(LHSConstant: ValueRef, RHSConstant: ValueRef) ->
unsafe fn LLVMConstAShr(LHSConstant: ValueRef, RHSConstant: ValueRef) ->
ValueRef;
fn LLVMConstSub(LHSConstant: ValueRef, RHSConstant: ValueRef) -> ValueRef;
fn LLVMConstNSWSub(LHSConstant: ValueRef, RHSConstant: ValueRef) ->
ValueRef;
fn LLVMConstNUWSub(LHSConstant: ValueRef, RHSConstant: ValueRef) ->
ValueRef;
fn LLVMConstFSub(LHSConstant: ValueRef, RHSConstant: ValueRef) ->
ValueRef;
fn LLVMConstMul(LHSConstant: ValueRef, RHSConstant: ValueRef) -> ValueRef;
fn LLVMConstNSWMul(LHSConstant: ValueRef, RHSConstant: ValueRef) ->
ValueRef;
fn LLVMConstNUWMul(LHSConstant: ValueRef, RHSConstant: ValueRef) ->
ValueRef;
fn LLVMConstFMul(LHSConstant: ValueRef, RHSConstant: ValueRef) ->
ValueRef;
fn LLVMConstUDiv(LHSConstant: ValueRef, RHSConstant: ValueRef) ->
ValueRef;
fn LLVMConstSDiv(LHSConstant: ValueRef, RHSConstant: ValueRef) ->
ValueRef;
fn LLVMConstExactSDiv(LHSConstant: ValueRef, RHSConstant: ValueRef) ->
ValueRef;
fn LLVMConstFDiv(LHSConstant: ValueRef, RHSConstant: ValueRef) ->
ValueRef;
fn LLVMConstURem(LHSConstant: ValueRef, RHSConstant: ValueRef) ->
ValueRef;
fn LLVMConstSRem(LHSConstant: ValueRef, RHSConstant: ValueRef) ->
ValueRef;
fn LLVMConstFRem(LHSConstant: ValueRef, RHSConstant: ValueRef) ->
ValueRef;
fn LLVMConstAnd(LHSConstant: ValueRef, RHSConstant: ValueRef) -> ValueRef;
fn LLVMConstOr(LHSConstant: ValueRef, RHSConstant: ValueRef) -> ValueRef;
fn LLVMConstXor(LHSConstant: ValueRef, RHSConstant: ValueRef) -> ValueRef;
fn LLVMConstShl(LHSConstant: ValueRef, RHSConstant: ValueRef) -> ValueRef;
fn LLVMConstLShr(LHSConstant: ValueRef, RHSConstant: ValueRef) ->
ValueRef;
fn LLVMConstAShr(LHSConstant: ValueRef, RHSConstant: ValueRef) ->
ValueRef;
fn LLVMConstGEP(ConstantVal: ValueRef,
unsafe fn LLVMConstGEP(ConstantVal: ValueRef,
ConstantIndices: *ValueRef,
NumIndices: c_uint) -> ValueRef;
fn LLVMConstInBoundsGEP(ConstantVal: ValueRef,
ConstantIndices: *ValueRef,
NumIndices: c_uint) -> ValueRef;
fn LLVMConstTrunc(ConstantVal: ValueRef, ToType: TypeRef) -> ValueRef;
fn LLVMConstSExt(ConstantVal: ValueRef, ToType: TypeRef) -> ValueRef;
fn LLVMConstZExt(ConstantVal: ValueRef, ToType: TypeRef) -> ValueRef;
fn LLVMConstFPTrunc(ConstantVal: ValueRef, ToType: TypeRef) -> ValueRef;
fn LLVMConstFPExt(ConstantVal: ValueRef, ToType: TypeRef) -> ValueRef;
fn LLVMConstUIToFP(ConstantVal: ValueRef, ToType: TypeRef) -> ValueRef;
fn LLVMConstSIToFP(ConstantVal: ValueRef, ToType: TypeRef) -> ValueRef;
fn LLVMConstFPToUI(ConstantVal: ValueRef, ToType: TypeRef) -> ValueRef;
fn LLVMConstFPToSI(ConstantVal: ValueRef, ToType: TypeRef) -> ValueRef;
fn LLVMConstPtrToInt(ConstantVal: ValueRef, ToType: TypeRef) -> ValueRef;
fn LLVMConstIntToPtr(ConstantVal: ValueRef, ToType: TypeRef) -> ValueRef;
fn LLVMConstBitCast(ConstantVal: ValueRef, ToType: TypeRef) -> ValueRef;
fn LLVMConstZExtOrBitCast(ConstantVal: ValueRef, ToType: TypeRef) ->
ValueRef;
fn LLVMConstSExtOrBitCast(ConstantVal: ValueRef, ToType: TypeRef) ->
ValueRef;
fn LLVMConstTruncOrBitCast(ConstantVal: ValueRef, ToType: TypeRef) ->
ValueRef;
fn LLVMConstPointerCast(ConstantVal: ValueRef, ToType: TypeRef) ->
ValueRef;
fn LLVMConstIntCast(ConstantVal: ValueRef, ToType: TypeRef,
unsafe fn LLVMConstInBoundsGEP(ConstantVal: ValueRef,
ConstantIndices: *ValueRef,
NumIndices: c_uint)
-> ValueRef;
unsafe fn LLVMConstTrunc(ConstantVal: ValueRef,
ToType: TypeRef)
-> ValueRef;
unsafe fn LLVMConstSExt(ConstantVal: ValueRef,
ToType: TypeRef)
-> ValueRef;
unsafe fn LLVMConstZExt(ConstantVal: ValueRef,
ToType: TypeRef)
-> ValueRef;
unsafe fn LLVMConstFPTrunc(ConstantVal: ValueRef,
ToType: TypeRef)
-> ValueRef;
unsafe fn LLVMConstFPExt(ConstantVal: ValueRef,
ToType: TypeRef)
-> ValueRef;
unsafe fn LLVMConstUIToFP(ConstantVal: ValueRef,
ToType: TypeRef)
-> ValueRef;
unsafe fn LLVMConstSIToFP(ConstantVal: ValueRef,
ToType: TypeRef)
-> ValueRef;
unsafe fn LLVMConstFPToUI(ConstantVal: ValueRef,
ToType: TypeRef)
-> ValueRef;
unsafe fn LLVMConstFPToSI(ConstantVal: ValueRef,
ToType: TypeRef)
-> ValueRef;
unsafe fn LLVMConstPtrToInt(ConstantVal: ValueRef,
ToType: TypeRef)
-> ValueRef;
unsafe fn LLVMConstIntToPtr(ConstantVal: ValueRef,
ToType: TypeRef)
-> ValueRef;
unsafe fn LLVMConstBitCast(ConstantVal: ValueRef,
ToType: TypeRef)
-> ValueRef;
unsafe fn LLVMConstZExtOrBitCast(ConstantVal: ValueRef,
ToType: TypeRef)
-> ValueRef;
unsafe fn LLVMConstSExtOrBitCast(ConstantVal: ValueRef,
ToType: TypeRef)
-> ValueRef;
unsafe fn LLVMConstTruncOrBitCast(ConstantVal: ValueRef,
ToType: TypeRef)
-> ValueRef;
unsafe fn LLVMConstPointerCast(ConstantVal: ValueRef,
ToType: TypeRef)
-> ValueRef;
unsafe fn LLVMConstIntCast(ConstantVal: ValueRef, ToType: TypeRef,
isSigned: Bool) -> ValueRef;
fn LLVMConstFPCast(ConstantVal: ValueRef, ToType: TypeRef) -> ValueRef;
fn LLVMConstSelect(ConstantCondition: ValueRef, ConstantIfTrue: ValueRef,
ConstantIfFalse: ValueRef) -> ValueRef;
fn LLVMConstExtractElement(VectorConstant: ValueRef,
unsafe fn LLVMConstFPCast(ConstantVal: ValueRef,
ToType: TypeRef)
-> ValueRef;
unsafe fn LLVMConstSelect(ConstantCondition: ValueRef,
ConstantIfTrue: ValueRef,
ConstantIfFalse: ValueRef)
-> ValueRef;
unsafe fn LLVMConstExtractElement(VectorConstant: ValueRef,
IndexConstant: ValueRef) -> ValueRef;
fn LLVMConstInsertElement(VectorConstant: ValueRef,
unsafe fn LLVMConstInsertElement(VectorConstant: ValueRef,
ElementValueConstant: ValueRef,
IndexConstant: ValueRef) -> ValueRef;
fn LLVMConstShuffleVector(VectorAConstant: ValueRef,
unsafe fn LLVMConstShuffleVector(VectorAConstant: ValueRef,
VectorBConstant: ValueRef,
MaskConstant: ValueRef) -> ValueRef;
fn LLVMConstExtractValue(AggConstant: ValueRef, IdxList: *c_uint,
unsafe fn LLVMConstExtractValue(AggConstant: ValueRef, IdxList: *c_uint,
NumIdx: c_uint) -> ValueRef;
fn LLVMConstInsertValue(AggConstant: ValueRef,
unsafe fn LLVMConstInsertValue(AggConstant: ValueRef,
ElementValueConstant: ValueRef, IdxList: *c_uint,
NumIdx: c_uint) -> ValueRef;
fn LLVMConstInlineAsm(Ty: TypeRef, AsmString: *c_char,
unsafe fn LLVMConstInlineAsm(Ty: TypeRef, AsmString: *c_char,
Constraints: *c_char, HasSideEffects: Bool,
IsAlignStack: Bool) -> ValueRef;
fn LLVMBlockAddress(F: ValueRef, BB: BasicBlockRef) -> ValueRef;
unsafe fn LLVMBlockAddress(F: ValueRef, BB: BasicBlockRef) -> ValueRef;
/* Operations on global variables, functions, and aliases (globals) */
fn LLVMGetGlobalParent(Global: ValueRef) -> ModuleRef;
fn LLVMIsDeclaration(Global: ValueRef) -> Bool;
fn LLVMGetLinkage(Global: ValueRef) -> c_uint;
fn LLVMSetLinkage(Global: ValueRef, Link: c_uint);
fn LLVMGetSection(Global: ValueRef) -> *c_char;
fn LLVMSetSection(Global: ValueRef, Section: *c_char);
fn LLVMGetVisibility(Global: ValueRef) -> c_uint;
fn LLVMSetVisibility(Global: ValueRef, Viz: c_uint);
fn LLVMGetAlignment(Global: ValueRef) -> c_uint;
fn LLVMSetAlignment(Global: ValueRef, Bytes: c_uint);
unsafe fn LLVMGetGlobalParent(Global: ValueRef) -> ModuleRef;
unsafe fn LLVMIsDeclaration(Global: ValueRef) -> Bool;
unsafe fn LLVMGetLinkage(Global: ValueRef) -> c_uint;
unsafe fn LLVMSetLinkage(Global: ValueRef, Link: c_uint);
unsafe fn LLVMGetSection(Global: ValueRef) -> *c_char;
unsafe fn LLVMSetSection(Global: ValueRef, Section: *c_char);
unsafe fn LLVMGetVisibility(Global: ValueRef) -> c_uint;
unsafe fn LLVMSetVisibility(Global: ValueRef, Viz: c_uint);
unsafe fn LLVMGetAlignment(Global: ValueRef) -> c_uint;
unsafe fn LLVMSetAlignment(Global: ValueRef, Bytes: c_uint);
/* Operations on global variables */
fn LLVMAddGlobal(M: ModuleRef, Ty: TypeRef, Name: *c_char) -> ValueRef;
fn LLVMAddGlobalInAddressSpace(M: ModuleRef, Ty: TypeRef, Name: *c_char,
AddressSpace: c_uint) -> ValueRef;
fn LLVMGetNamedGlobal(M: ModuleRef, Name: *c_char) -> ValueRef;
fn LLVMGetFirstGlobal(M: ModuleRef) -> ValueRef;
fn LLVMGetLastGlobal(M: ModuleRef) -> ValueRef;
fn LLVMGetNextGlobal(GlobalVar: ValueRef) -> ValueRef;
fn LLVMGetPreviousGlobal(GlobalVar: ValueRef) -> ValueRef;
fn LLVMDeleteGlobal(GlobalVar: ValueRef);
fn LLVMGetInitializer(GlobalVar: ValueRef) -> ValueRef;
fn LLVMSetInitializer(GlobalVar: ValueRef, ConstantVal: ValueRef);
fn LLVMIsThreadLocal(GlobalVar: ValueRef) -> Bool;
fn LLVMSetThreadLocal(GlobalVar: ValueRef, IsThreadLocal: Bool);
fn LLVMIsGlobalConstant(GlobalVar: ValueRef) -> Bool;
fn LLVMSetGlobalConstant(GlobalVar: ValueRef, IsConstant: Bool);
unsafe fn LLVMAddGlobal(M: ModuleRef,
Ty: TypeRef,
Name: *c_char)
-> ValueRef;
unsafe fn LLVMAddGlobalInAddressSpace(M: ModuleRef,
Ty: TypeRef,
Name: *c_char,
AddressSpace: c_uint)
-> ValueRef;
unsafe fn LLVMGetNamedGlobal(M: ModuleRef, Name: *c_char) -> ValueRef;
unsafe fn LLVMGetFirstGlobal(M: ModuleRef) -> ValueRef;
unsafe fn LLVMGetLastGlobal(M: ModuleRef) -> ValueRef;
unsafe fn LLVMGetNextGlobal(GlobalVar: ValueRef) -> ValueRef;
unsafe fn LLVMGetPreviousGlobal(GlobalVar: ValueRef) -> ValueRef;
unsafe fn LLVMDeleteGlobal(GlobalVar: ValueRef);
unsafe fn LLVMGetInitializer(GlobalVar: ValueRef) -> ValueRef;
unsafe fn LLVMSetInitializer(GlobalVar: ValueRef, ConstantVal: ValueRef);
unsafe fn LLVMIsThreadLocal(GlobalVar: ValueRef) -> Bool;
unsafe fn LLVMSetThreadLocal(GlobalVar: ValueRef, IsThreadLocal: Bool);
unsafe fn LLVMIsGlobalConstant(GlobalVar: ValueRef) -> Bool;
unsafe fn LLVMSetGlobalConstant(GlobalVar: ValueRef, IsConstant: Bool);
/* Operations on aliases */
fn LLVMAddAlias(M: ModuleRef, Ty: TypeRef, Aliasee: ValueRef,
unsafe fn LLVMAddAlias(M: ModuleRef, Ty: TypeRef, Aliasee: ValueRef,
Name: *c_char) -> ValueRef;
/* Operations on functions */
fn LLVMAddFunction(M: ModuleRef, Name: *c_char, FunctionTy: TypeRef) ->
ValueRef;
fn LLVMGetNamedFunction(M: ModuleRef, Name: *c_char) -> ValueRef;
fn LLVMGetFirstFunction(M: ModuleRef) -> ValueRef;
fn LLVMGetLastFunction(M: ModuleRef) -> ValueRef;
fn LLVMGetNextFunction(Fn: ValueRef) -> ValueRef;
fn LLVMGetPreviousFunction(Fn: ValueRef) -> ValueRef;
fn LLVMDeleteFunction(Fn: ValueRef);
fn LLVMGetOrInsertFunction(M: ModuleRef, Name: *c_char,
unsafe fn LLVMAddFunction(M: ModuleRef,
Name: *c_char,
FunctionTy: TypeRef)
-> ValueRef;
unsafe fn LLVMGetNamedFunction(M: ModuleRef, Name: *c_char) -> ValueRef;
unsafe fn LLVMGetFirstFunction(M: ModuleRef) -> ValueRef;
unsafe fn LLVMGetLastFunction(M: ModuleRef) -> ValueRef;
unsafe fn LLVMGetNextFunction(Fn: ValueRef) -> ValueRef;
unsafe fn LLVMGetPreviousFunction(Fn: ValueRef) -> ValueRef;
unsafe fn LLVMDeleteFunction(Fn: ValueRef);
unsafe fn LLVMGetOrInsertFunction(M: ModuleRef, Name: *c_char,
FunctionTy: TypeRef) -> ValueRef;
fn LLVMGetIntrinsicID(Fn: ValueRef) -> c_uint;
fn LLVMGetFunctionCallConv(Fn: ValueRef) -> c_uint;
fn LLVMSetFunctionCallConv(Fn: ValueRef, CC: c_uint);
fn LLVMGetGC(Fn: ValueRef) -> *c_char;
fn LLVMSetGC(Fn: ValueRef, Name: *c_char);
fn LLVMAddFunctionAttr(Fn: ValueRef, PA: c_ulonglong, HighPA:
unsafe fn LLVMGetIntrinsicID(Fn: ValueRef) -> c_uint;
unsafe fn LLVMGetFunctionCallConv(Fn: ValueRef) -> c_uint;
unsafe fn LLVMSetFunctionCallConv(Fn: ValueRef, CC: c_uint);
unsafe fn LLVMGetGC(Fn: ValueRef) -> *c_char;
unsafe fn LLVMSetGC(Fn: ValueRef, Name: *c_char);
unsafe fn LLVMAddFunctionAttr(Fn: ValueRef, PA: c_ulonglong, HighPA:
c_ulonglong);
fn LLVMGetFunctionAttr(Fn: ValueRef) -> c_ulonglong;
fn LLVMRemoveFunctionAttr(Fn: ValueRef, PA: c_ulonglong, HighPA:
unsafe fn LLVMGetFunctionAttr(Fn: ValueRef) -> c_ulonglong;
unsafe fn LLVMRemoveFunctionAttr(Fn: ValueRef, PA: c_ulonglong, HighPA:
c_ulonglong);
/* Operations on parameters */
fn LLVMCountParams(Fn: ValueRef) -> c_uint;
fn LLVMGetParams(Fn: ValueRef, Params: *ValueRef);
fn LLVMGetParam(Fn: ValueRef, Index: c_uint) -> ValueRef;
fn LLVMGetParamParent(Inst: ValueRef) -> ValueRef;
fn LLVMGetFirstParam(Fn: ValueRef) -> ValueRef;
fn LLVMGetLastParam(Fn: ValueRef) -> ValueRef;
fn LLVMGetNextParam(Arg: ValueRef) -> ValueRef;
fn LLVMGetPreviousParam(Arg: ValueRef) -> ValueRef;
fn LLVMAddAttribute(Arg: ValueRef, PA: c_uint);
fn LLVMRemoveAttribute(Arg: ValueRef, PA: c_uint);
fn LLVMGetAttribute(Arg: ValueRef) -> c_uint;
fn LLVMSetParamAlignment(Arg: ValueRef, align: c_uint);
unsafe fn LLVMCountParams(Fn: ValueRef) -> c_uint;
unsafe fn LLVMGetParams(Fn: ValueRef, Params: *ValueRef);
unsafe fn LLVMGetParam(Fn: ValueRef, Index: c_uint) -> ValueRef;
unsafe fn LLVMGetParamParent(Inst: ValueRef) -> ValueRef;
unsafe fn LLVMGetFirstParam(Fn: ValueRef) -> ValueRef;
unsafe fn LLVMGetLastParam(Fn: ValueRef) -> ValueRef;
unsafe fn LLVMGetNextParam(Arg: ValueRef) -> ValueRef;
unsafe fn LLVMGetPreviousParam(Arg: ValueRef) -> ValueRef;
unsafe fn LLVMAddAttribute(Arg: ValueRef, PA: c_uint);
unsafe fn LLVMRemoveAttribute(Arg: ValueRef, PA: c_uint);
unsafe fn LLVMGetAttribute(Arg: ValueRef) -> c_uint;
unsafe fn LLVMSetParamAlignment(Arg: ValueRef, align: c_uint);
/* Operations on basic blocks */
fn LLVMBasicBlockAsValue(BB: BasicBlockRef) -> ValueRef;
fn LLVMValueIsBasicBlock(Val: ValueRef) -> Bool;
fn LLVMValueAsBasicBlock(Val: ValueRef) -> BasicBlockRef;
fn LLVMGetBasicBlockParent(BB: BasicBlockRef) -> ValueRef;
fn LLVMCountBasicBlocks(Fn: ValueRef) -> c_uint;
fn LLVMGetBasicBlocks(Fn: ValueRef, BasicBlocks: *ValueRef);
fn LLVMGetFirstBasicBlock(Fn: ValueRef) -> BasicBlockRef;
fn LLVMGetLastBasicBlock(Fn: ValueRef) -> BasicBlockRef;
fn LLVMGetNextBasicBlock(BB: BasicBlockRef) -> BasicBlockRef;
fn LLVMGetPreviousBasicBlock(BB: BasicBlockRef) -> BasicBlockRef;
fn LLVMGetEntryBasicBlock(Fn: ValueRef) -> BasicBlockRef;
unsafe fn LLVMBasicBlockAsValue(BB: BasicBlockRef) -> ValueRef;
unsafe fn LLVMValueIsBasicBlock(Val: ValueRef) -> Bool;
unsafe fn LLVMValueAsBasicBlock(Val: ValueRef) -> BasicBlockRef;
unsafe fn LLVMGetBasicBlockParent(BB: BasicBlockRef) -> ValueRef;
unsafe fn LLVMCountBasicBlocks(Fn: ValueRef) -> c_uint;
unsafe fn LLVMGetBasicBlocks(Fn: ValueRef, BasicBlocks: *ValueRef);
unsafe fn LLVMGetFirstBasicBlock(Fn: ValueRef) -> BasicBlockRef;
unsafe fn LLVMGetLastBasicBlock(Fn: ValueRef) -> BasicBlockRef;
unsafe fn LLVMGetNextBasicBlock(BB: BasicBlockRef) -> BasicBlockRef;
unsafe fn LLVMGetPreviousBasicBlock(BB: BasicBlockRef) -> BasicBlockRef;
unsafe fn LLVMGetEntryBasicBlock(Fn: ValueRef) -> BasicBlockRef;
fn LLVMAppendBasicBlockInContext(C: ContextRef, Fn: ValueRef,
unsafe fn LLVMAppendBasicBlockInContext(C: ContextRef, Fn: ValueRef,
Name: *c_char) -> BasicBlockRef;
fn LLVMInsertBasicBlockInContext(C: ContextRef, BB: BasicBlockRef,
unsafe fn LLVMInsertBasicBlockInContext(C: ContextRef, BB: BasicBlockRef,
Name: *c_char) -> BasicBlockRef;
fn LLVMAppendBasicBlock(Fn: ValueRef, Name: *c_char) -> BasicBlockRef;
fn LLVMInsertBasicBlock(InsertBeforeBB: BasicBlockRef, Name: *c_char) ->
BasicBlockRef;
fn LLVMDeleteBasicBlock(BB: BasicBlockRef);
unsafe fn LLVMAppendBasicBlock(Fn: ValueRef,
Name: *c_char)
-> BasicBlockRef;
unsafe fn LLVMInsertBasicBlock(InsertBeforeBB: BasicBlockRef,
Name: *c_char)
-> BasicBlockRef;
unsafe fn LLVMDeleteBasicBlock(BB: BasicBlockRef);
/* Operations on instructions */
fn LLVMGetInstructionParent(Inst: ValueRef) -> BasicBlockRef;
fn LLVMGetFirstInstruction(BB: BasicBlockRef) -> ValueRef;
fn LLVMGetLastInstruction(BB: BasicBlockRef) -> ValueRef;
fn LLVMGetNextInstruction(Inst: ValueRef) -> ValueRef;
fn LLVMGetPreviousInstruction(Inst: ValueRef) -> ValueRef;
unsafe fn LLVMGetInstructionParent(Inst: ValueRef) -> BasicBlockRef;
unsafe fn LLVMGetFirstInstruction(BB: BasicBlockRef) -> ValueRef;
unsafe fn LLVMGetLastInstruction(BB: BasicBlockRef) -> ValueRef;
unsafe fn LLVMGetNextInstruction(Inst: ValueRef) -> ValueRef;
unsafe fn LLVMGetPreviousInstruction(Inst: ValueRef) -> ValueRef;
/* Operations on call sites */
fn LLVMSetInstructionCallConv(Instr: ValueRef, CC: c_uint);
fn LLVMGetInstructionCallConv(Instr: ValueRef) -> c_uint;
fn LLVMAddInstrAttribute(Instr: ValueRef, index: c_uint, IA: c_uint);
fn LLVMRemoveInstrAttribute(Instr: ValueRef, index: c_uint,
unsafe fn LLVMSetInstructionCallConv(Instr: ValueRef, CC: c_uint);
unsafe fn LLVMGetInstructionCallConv(Instr: ValueRef) -> c_uint;
unsafe fn LLVMAddInstrAttribute(Instr: ValueRef,
index: c_uint,
IA: c_uint);
unsafe fn LLVMRemoveInstrAttribute(Instr: ValueRef, index: c_uint,
IA: c_uint);
fn LLVMSetInstrParamAlignment(Instr: ValueRef, index: c_uint,
unsafe fn LLVMSetInstrParamAlignment(Instr: ValueRef, index: c_uint,
align: c_uint);
/* Operations on call instructions (only) */
fn LLVMIsTailCall(CallInst: ValueRef) -> Bool;
fn LLVMSetTailCall(CallInst: ValueRef, IsTailCall: Bool);
unsafe fn LLVMIsTailCall(CallInst: ValueRef) -> Bool;
unsafe fn LLVMSetTailCall(CallInst: ValueRef, IsTailCall: Bool);
/* Operations on phi nodes */
fn LLVMAddIncoming(PhiNode: ValueRef, IncomingValues: *ValueRef,
unsafe fn LLVMAddIncoming(PhiNode: ValueRef, IncomingValues: *ValueRef,
IncomingBlocks: *BasicBlockRef, Count: c_uint);
fn LLVMCountIncoming(PhiNode: ValueRef) -> c_uint;
fn LLVMGetIncomingValue(PhiNode: ValueRef, Index: c_uint) -> ValueRef;
fn LLVMGetIncomingBlock(PhiNode: ValueRef,
unsafe fn LLVMCountIncoming(PhiNode: ValueRef) -> c_uint;
unsafe fn LLVMGetIncomingValue(PhiNode: ValueRef,
Index: c_uint)
-> ValueRef;
unsafe fn LLVMGetIncomingBlock(PhiNode: ValueRef,
Index: c_uint) -> BasicBlockRef;
/* Instruction builders */
fn LLVMCreateBuilderInContext(C: ContextRef) -> BuilderRef;
fn LLVMCreateBuilder() -> BuilderRef;
fn LLVMPositionBuilder(Builder: BuilderRef, Block: BasicBlockRef,
unsafe fn LLVMCreateBuilderInContext(C: ContextRef) -> BuilderRef;
unsafe fn LLVMCreateBuilder() -> BuilderRef;
unsafe fn LLVMPositionBuilder(Builder: BuilderRef, Block: BasicBlockRef,
Instr: ValueRef);
fn LLVMPositionBuilderBefore(Builder: BuilderRef, Instr: ValueRef);
fn LLVMPositionBuilderAtEnd(Builder: BuilderRef, Block: BasicBlockRef);
fn LLVMGetInsertBlock(Builder: BuilderRef) -> BasicBlockRef;
fn LLVMClearInsertionPosition(Builder: BuilderRef);
fn LLVMInsertIntoBuilder(Builder: BuilderRef, Instr: ValueRef);
fn LLVMInsertIntoBuilderWithName(Builder: BuilderRef, Instr: ValueRef,
Name: *c_char);
fn LLVMDisposeBuilder(Builder: BuilderRef);
unsafe fn LLVMPositionBuilderBefore(Builder: BuilderRef, Instr: ValueRef);
unsafe fn LLVMPositionBuilderAtEnd(Builder: BuilderRef,
Block: BasicBlockRef);
unsafe fn LLVMGetInsertBlock(Builder: BuilderRef) -> BasicBlockRef;
unsafe fn LLVMClearInsertionPosition(Builder: BuilderRef);
unsafe fn LLVMInsertIntoBuilder(Builder: BuilderRef, Instr: ValueRef);
unsafe fn LLVMInsertIntoBuilderWithName(Builder: BuilderRef,
Instr: ValueRef,
Name: *c_char);
unsafe fn LLVMDisposeBuilder(Builder: BuilderRef);
/* Metadata */
fn LLVMSetCurrentDebugLocation(Builder: BuilderRef, L: ValueRef);
fn LLVMGetCurrentDebugLocation(Builder: BuilderRef) -> ValueRef;
fn LLVMSetInstDebugLocation(Builder: BuilderRef, Inst: ValueRef);
unsafe fn LLVMSetCurrentDebugLocation(Builder: BuilderRef, L: ValueRef);
unsafe fn LLVMGetCurrentDebugLocation(Builder: BuilderRef) -> ValueRef;
unsafe fn LLVMSetInstDebugLocation(Builder: BuilderRef, Inst: ValueRef);
/* Terminators */
fn LLVMBuildRetVoid(B: BuilderRef) -> ValueRef;
fn LLVMBuildRet(B: BuilderRef, V: ValueRef) -> ValueRef;
fn LLVMBuildAggregateRet(B: BuilderRef, RetVals: *ValueRef,
unsafe fn LLVMBuildRetVoid(B: BuilderRef) -> ValueRef;
unsafe fn LLVMBuildRet(B: BuilderRef, V: ValueRef) -> ValueRef;
unsafe fn LLVMBuildAggregateRet(B: BuilderRef, RetVals: *ValueRef,
N: c_uint) -> ValueRef;
fn LLVMBuildBr(B: BuilderRef, Dest: BasicBlockRef) -> ValueRef;
fn LLVMBuildCondBr(B: BuilderRef, If: ValueRef, Then: BasicBlockRef,
Else: BasicBlockRef) -> ValueRef;
fn LLVMBuildSwitch(B: BuilderRef, V: ValueRef, Else: BasicBlockRef,
unsafe fn LLVMBuildBr(B: BuilderRef, Dest: BasicBlockRef) -> ValueRef;
unsafe fn LLVMBuildCondBr(B: BuilderRef,
If: ValueRef,
Then: BasicBlockRef,
Else: BasicBlockRef)
-> ValueRef;
unsafe fn LLVMBuildSwitch(B: BuilderRef, V: ValueRef, Else: BasicBlockRef,
NumCases: c_uint) -> ValueRef;
fn LLVMBuildIndirectBr(B: BuilderRef, Addr: ValueRef,
unsafe fn LLVMBuildIndirectBr(B: BuilderRef, Addr: ValueRef,
NumDests: c_uint) -> ValueRef;
fn LLVMBuildInvoke(B: BuilderRef, Fn: ValueRef, Args: *ValueRef,
unsafe fn LLVMBuildInvoke(B: BuilderRef, Fn: ValueRef, Args: *ValueRef,
NumArgs: c_uint, Then: BasicBlockRef,
Catch: BasicBlockRef, Name: *c_char) -> ValueRef;
fn LLVMBuildLandingPad(B: BuilderRef, Ty: TypeRef, PersFn: ValueRef,
NumClauses: c_uint, Name: *c_char) -> ValueRef;
fn LLVMBuildResume(B: BuilderRef, Exn: ValueRef) -> ValueRef;
fn LLVMBuildUnreachable(B: BuilderRef) -> ValueRef;
unsafe fn LLVMBuildLandingPad(B: BuilderRef,
Ty: TypeRef,
PersFn: ValueRef,
NumClauses: c_uint,
Name: *c_char)
-> ValueRef;
unsafe fn LLVMBuildResume(B: BuilderRef, Exn: ValueRef) -> ValueRef;
unsafe fn LLVMBuildUnreachable(B: BuilderRef) -> ValueRef;
/* Add a case to the switch instruction */
fn LLVMAddCase(Switch: ValueRef, OnVal: ValueRef, Dest: BasicBlockRef);
unsafe fn LLVMAddCase(Switch: ValueRef,
OnVal: ValueRef,
Dest: BasicBlockRef);
/* Add a destination to the indirectbr instruction */
fn LLVMAddDestination(IndirectBr: ValueRef, Dest: BasicBlockRef);
unsafe fn LLVMAddDestination(IndirectBr: ValueRef, Dest: BasicBlockRef);
/* Add a clause to the landing pad instruction */
fn LLVMAddClause(LandingPad: ValueRef, ClauseVal: ValueRef);
unsafe fn LLVMAddClause(LandingPad: ValueRef, ClauseVal: ValueRef);
/* Set the cleanup on a landing pad instruction */
fn LLVMSetCleanup(LandingPad: ValueRef, Val: Bool);
unsafe fn LLVMSetCleanup(LandingPad: ValueRef, Val: Bool);
/* Arithmetic */
fn LLVMBuildAdd(B: BuilderRef, LHS: ValueRef, RHS: ValueRef,
unsafe fn LLVMBuildAdd(B: BuilderRef, LHS: ValueRef, RHS: ValueRef,
Name: *c_char) -> ValueRef;
fn LLVMBuildNSWAdd(B: BuilderRef, LHS: ValueRef, RHS: ValueRef,
unsafe fn LLVMBuildNSWAdd(B: BuilderRef, LHS: ValueRef, RHS: ValueRef,
Name: *c_char) -> ValueRef;
fn LLVMBuildNUWAdd(B: BuilderRef, LHS: ValueRef, RHS: ValueRef,
unsafe fn LLVMBuildNUWAdd(B: BuilderRef, LHS: ValueRef, RHS: ValueRef,
Name: *c_char) -> ValueRef;
fn LLVMBuildFAdd(B: BuilderRef, LHS: ValueRef, RHS: ValueRef,
unsafe fn LLVMBuildFAdd(B: BuilderRef, LHS: ValueRef, RHS: ValueRef,
Name: *c_char) -> ValueRef;
fn LLVMBuildSub(B: BuilderRef, LHS: ValueRef, RHS: ValueRef,
unsafe fn LLVMBuildSub(B: BuilderRef, LHS: ValueRef, RHS: ValueRef,
Name: *c_char) -> ValueRef;
fn LLVMBuildNSWSub(B: BuilderRef, LHS: ValueRef, RHS: ValueRef,
unsafe fn LLVMBuildNSWSub(B: BuilderRef, LHS: ValueRef, RHS: ValueRef,
Name: *c_char) -> ValueRef;
fn LLVMBuildNUWSub(B: BuilderRef, LHS: ValueRef, RHS: ValueRef,
unsafe fn LLVMBuildNUWSub(B: BuilderRef, LHS: ValueRef, RHS: ValueRef,
Name: *c_char) -> ValueRef;
fn LLVMBuildFSub(B: BuilderRef, LHS: ValueRef, RHS: ValueRef,
unsafe fn LLVMBuildFSub(B: BuilderRef, LHS: ValueRef, RHS: ValueRef,
Name: *c_char) -> ValueRef;
fn LLVMBuildMul(B: BuilderRef, LHS: ValueRef, RHS: ValueRef,
unsafe fn LLVMBuildMul(B: BuilderRef, LHS: ValueRef, RHS: ValueRef,
Name: *c_char) -> ValueRef;
fn LLVMBuildNSWMul(B: BuilderRef, LHS: ValueRef, RHS: ValueRef,
unsafe fn LLVMBuildNSWMul(B: BuilderRef, LHS: ValueRef, RHS: ValueRef,
Name: *c_char) -> ValueRef;
fn LLVMBuildNUWMul(B: BuilderRef, LHS: ValueRef, RHS: ValueRef,
unsafe fn LLVMBuildNUWMul(B: BuilderRef, LHS: ValueRef, RHS: ValueRef,
Name: *c_char) -> ValueRef;
fn LLVMBuildFMul(B: BuilderRef, LHS: ValueRef, RHS: ValueRef,
unsafe fn LLVMBuildFMul(B: BuilderRef, LHS: ValueRef, RHS: ValueRef,
Name: *c_char) -> ValueRef;
fn LLVMBuildUDiv(B: BuilderRef, LHS: ValueRef, RHS: ValueRef,
unsafe fn LLVMBuildUDiv(B: BuilderRef, LHS: ValueRef, RHS: ValueRef,
Name: *c_char) -> ValueRef;
fn LLVMBuildSDiv(B: BuilderRef, LHS: ValueRef, RHS: ValueRef,
unsafe fn LLVMBuildSDiv(B: BuilderRef, LHS: ValueRef, RHS: ValueRef,
Name: *c_char) -> ValueRef;
fn LLVMBuildExactSDiv(B: BuilderRef, LHS: ValueRef, RHS: ValueRef,
unsafe fn LLVMBuildExactSDiv(B: BuilderRef, LHS: ValueRef, RHS: ValueRef,
Name: *c_char) -> ValueRef;
fn LLVMBuildFDiv(B: BuilderRef, LHS: ValueRef, RHS: ValueRef,
unsafe fn LLVMBuildFDiv(B: BuilderRef, LHS: ValueRef, RHS: ValueRef,
Name: *c_char) -> ValueRef;
fn LLVMBuildURem(B: BuilderRef, LHS: ValueRef, RHS: ValueRef,
unsafe fn LLVMBuildURem(B: BuilderRef, LHS: ValueRef, RHS: ValueRef,
Name: *c_char) -> ValueRef;
fn LLVMBuildSRem(B: BuilderRef, LHS: ValueRef, RHS: ValueRef,
unsafe fn LLVMBuildSRem(B: BuilderRef, LHS: ValueRef, RHS: ValueRef,
Name: *c_char) -> ValueRef;
fn LLVMBuildFRem(B: BuilderRef, LHS: ValueRef, RHS: ValueRef,
unsafe fn LLVMBuildFRem(B: BuilderRef, LHS: ValueRef, RHS: ValueRef,
Name: *c_char) -> ValueRef;
fn LLVMBuildShl(B: BuilderRef, LHS: ValueRef, RHS: ValueRef,
unsafe fn LLVMBuildShl(B: BuilderRef, LHS: ValueRef, RHS: ValueRef,
Name: *c_char) -> ValueRef;
fn LLVMBuildLShr(B: BuilderRef, LHS: ValueRef, RHS: ValueRef,
unsafe fn LLVMBuildLShr(B: BuilderRef, LHS: ValueRef, RHS: ValueRef,
Name: *c_char) -> ValueRef;
fn LLVMBuildAShr(B: BuilderRef, LHS: ValueRef, RHS: ValueRef,
unsafe fn LLVMBuildAShr(B: BuilderRef, LHS: ValueRef, RHS: ValueRef,
Name: *c_char) -> ValueRef;
fn LLVMBuildAnd(B: BuilderRef, LHS: ValueRef, RHS: ValueRef,
unsafe fn LLVMBuildAnd(B: BuilderRef, LHS: ValueRef, RHS: ValueRef,
Name: *c_char) -> ValueRef;
fn LLVMBuildOr(B: BuilderRef, LHS: ValueRef, RHS: ValueRef,
unsafe fn LLVMBuildOr(B: BuilderRef, LHS: ValueRef, RHS: ValueRef,
Name: *c_char) -> ValueRef;
fn LLVMBuildXor(B: BuilderRef, LHS: ValueRef, RHS: ValueRef,
unsafe fn LLVMBuildXor(B: BuilderRef, LHS: ValueRef, RHS: ValueRef,
Name: *c_char) -> ValueRef;
fn LLVMBuildBinOp(B: BuilderRef, Op: Opcode, LHS: ValueRef, RHS: ValueRef,
Name: *c_char) -> ValueRef;
fn LLVMBuildNeg(B: BuilderRef, V: ValueRef, Name: *c_char) -> ValueRef;
fn LLVMBuildNSWNeg(B: BuilderRef, V: ValueRef, Name: *c_char) -> ValueRef;
fn LLVMBuildNUWNeg(B: BuilderRef, V: ValueRef, Name: *c_char) -> ValueRef;
fn LLVMBuildFNeg(B: BuilderRef, V: ValueRef, Name: *c_char) -> ValueRef;
fn LLVMBuildNot(B: BuilderRef, V: ValueRef, Name: *c_char) -> ValueRef;
unsafe fn LLVMBuildBinOp(B: BuilderRef,
Op: Opcode,
LHS: ValueRef,
RHS: ValueRef,
Name: *c_char)
-> ValueRef;
unsafe fn LLVMBuildNeg(B: BuilderRef,
V: ValueRef,
Name: *c_char)
-> ValueRef;
unsafe fn LLVMBuildNSWNeg(B: BuilderRef,
V: ValueRef,
Name: *c_char)
-> ValueRef;
unsafe fn LLVMBuildNUWNeg(B: BuilderRef,
V: ValueRef,
Name: *c_char)
-> ValueRef;
unsafe fn LLVMBuildFNeg(B: BuilderRef,
V: ValueRef,
Name: *c_char)
-> ValueRef;
unsafe fn LLVMBuildNot(B: BuilderRef,
V: ValueRef,
Name: *c_char)
-> ValueRef;
/* Memory */
fn LLVMBuildMalloc(B: BuilderRef, Ty: TypeRef, Name: *c_char) -> ValueRef;
fn LLVMBuildArrayMalloc(B: BuilderRef, Ty: TypeRef, Val: ValueRef,
unsafe fn LLVMBuildMalloc(B: BuilderRef,
Ty: TypeRef,
Name: *c_char)
-> ValueRef;
unsafe fn LLVMBuildArrayMalloc(B: BuilderRef, Ty: TypeRef, Val: ValueRef,
Name: *c_char) -> ValueRef;
fn LLVMBuildAlloca(B: BuilderRef, Ty: TypeRef, Name: *c_char) -> ValueRef;
fn LLVMBuildArrayAlloca(B: BuilderRef, Ty: TypeRef, Val: ValueRef,
unsafe fn LLVMBuildAlloca(B: BuilderRef,
Ty: TypeRef,
Name: *c_char)
-> ValueRef;
unsafe fn LLVMBuildArrayAlloca(B: BuilderRef, Ty: TypeRef, Val: ValueRef,
Name: *c_char) -> ValueRef;
fn LLVMBuildFree(B: BuilderRef, PointerVal: ValueRef) -> ValueRef;
fn LLVMBuildLoad(B: BuilderRef, PointerVal: ValueRef, Name: *c_char) ->
unsafe fn LLVMBuildFree(B: BuilderRef, PointerVal: ValueRef) -> ValueRef;
unsafe fn LLVMBuildLoad(B: BuilderRef,
PointerVal: ValueRef,
Name: *c_char)
-> ValueRef;
unsafe fn LLVMBuildStore(B: BuilderRef, Val: ValueRef, Ptr: ValueRef) ->
ValueRef;
fn LLVMBuildStore(B: BuilderRef, Val: ValueRef, Ptr: ValueRef) ->
ValueRef;
fn LLVMBuildGEP(B: BuilderRef, Pointer: ValueRef, Indices: *ValueRef,
NumIndices: c_uint, Name: *c_char) -> ValueRef;
fn LLVMBuildInBoundsGEP(B: BuilderRef, Pointer: ValueRef,
unsafe fn LLVMBuildGEP(B: BuilderRef,
Pointer: ValueRef,
Indices: *ValueRef,
NumIndices: c_uint,
Name: *c_char)
-> ValueRef;
unsafe fn LLVMBuildInBoundsGEP(B: BuilderRef, Pointer: ValueRef,
Indices: *ValueRef, NumIndices: c_uint,
Name: *c_char)
-> ValueRef;
fn LLVMBuildStructGEP(B: BuilderRef, Pointer: ValueRef, Idx: c_uint,
Name: *c_char) -> ValueRef;
fn LLVMBuildGlobalString(B: BuilderRef, Str: *c_char, Name: *c_char) ->
ValueRef;
fn LLVMBuildGlobalStringPtr(B: BuilderRef, Str: *c_char, Name: *c_char) ->
ValueRef;
unsafe fn LLVMBuildStructGEP(B: BuilderRef,
Pointer: ValueRef,
Idx: c_uint,
Name: *c_char)
-> ValueRef;
unsafe fn LLVMBuildGlobalString(B: BuilderRef,
Str: *c_char,
Name: *c_char)
-> ValueRef;
unsafe fn LLVMBuildGlobalStringPtr(B: BuilderRef,
Str: *c_char,
Name: *c_char)
-> ValueRef;
/* Casts */
fn LLVMBuildTrunc(B: BuilderRef, Val: ValueRef, DestTy: TypeRef,
unsafe fn LLVMBuildTrunc(B: BuilderRef, Val: ValueRef, DestTy: TypeRef,
Name: *c_char) -> ValueRef;
fn LLVMBuildZExt(B: BuilderRef, Val: ValueRef, DestTy: TypeRef,
unsafe fn LLVMBuildZExt(B: BuilderRef, Val: ValueRef, DestTy: TypeRef,
Name: *c_char) -> ValueRef;
fn LLVMBuildSExt(B: BuilderRef, Val: ValueRef, DestTy: TypeRef,
unsafe fn LLVMBuildSExt(B: BuilderRef, Val: ValueRef, DestTy: TypeRef,
Name: *c_char) -> ValueRef;
fn LLVMBuildFPToUI(B: BuilderRef, Val: ValueRef, DestTy: TypeRef,
unsafe fn LLVMBuildFPToUI(B: BuilderRef, Val: ValueRef, DestTy: TypeRef,
Name: *c_char) -> ValueRef;
fn LLVMBuildFPToSI(B: BuilderRef, Val: ValueRef, DestTy: TypeRef,
unsafe fn LLVMBuildFPToSI(B: BuilderRef, Val: ValueRef, DestTy: TypeRef,
Name: *c_char) -> ValueRef;
fn LLVMBuildUIToFP(B: BuilderRef, Val: ValueRef, DestTy: TypeRef,
unsafe fn LLVMBuildUIToFP(B: BuilderRef, Val: ValueRef, DestTy: TypeRef,
Name: *c_char) -> ValueRef;
fn LLVMBuildSIToFP(B: BuilderRef, Val: ValueRef, DestTy: TypeRef,
unsafe fn LLVMBuildSIToFP(B: BuilderRef, Val: ValueRef, DestTy: TypeRef,
Name: *c_char) -> ValueRef;
fn LLVMBuildFPTrunc(B: BuilderRef, Val: ValueRef, DestTy: TypeRef,
unsafe fn LLVMBuildFPTrunc(B: BuilderRef, Val: ValueRef, DestTy: TypeRef,
Name: *c_char) -> ValueRef;
fn LLVMBuildFPExt(B: BuilderRef, Val: ValueRef, DestTy: TypeRef,
unsafe fn LLVMBuildFPExt(B: BuilderRef, Val: ValueRef, DestTy: TypeRef,
Name: *c_char) -> ValueRef;
fn LLVMBuildPtrToInt(B: BuilderRef, Val: ValueRef, DestTy: TypeRef,
unsafe fn LLVMBuildPtrToInt(B: BuilderRef, Val: ValueRef, DestTy: TypeRef,
Name: *c_char) -> ValueRef;
fn LLVMBuildIntToPtr(B: BuilderRef, Val: ValueRef, DestTy: TypeRef,
unsafe fn LLVMBuildIntToPtr(B: BuilderRef, Val: ValueRef, DestTy: TypeRef,
Name: *c_char) -> ValueRef;
fn LLVMBuildBitCast(B: BuilderRef, Val: ValueRef, DestTy: TypeRef,
unsafe fn LLVMBuildBitCast(B: BuilderRef, Val: ValueRef, DestTy: TypeRef,
Name: *c_char) -> ValueRef;
fn LLVMBuildZExtOrBitCast(B: BuilderRef, Val: ValueRef, DestTy: TypeRef,
Name: *c_char) -> ValueRef;
fn LLVMBuildSExtOrBitCast(B: BuilderRef, Val: ValueRef, DestTy: TypeRef,
Name: *c_char) -> ValueRef;
fn LLVMBuildTruncOrBitCast(B: BuilderRef, Val: ValueRef, DestTy: TypeRef,
Name: *c_char) -> ValueRef;
fn LLVMBuildCast(B: BuilderRef, Op: Opcode, Val: ValueRef,
unsafe fn LLVMBuildZExtOrBitCast(B: BuilderRef,
Val: ValueRef,
DestTy: TypeRef,
Name: *c_char)
-> ValueRef;
unsafe fn LLVMBuildSExtOrBitCast(B: BuilderRef,
Val: ValueRef,
DestTy: TypeRef,
Name: *c_char)
-> ValueRef;
unsafe fn LLVMBuildTruncOrBitCast(B: BuilderRef,
Val: ValueRef,
DestTy: TypeRef,
Name: *c_char)
-> ValueRef;
unsafe fn LLVMBuildCast(B: BuilderRef, Op: Opcode, Val: ValueRef,
DestTy: TypeRef, Name: *c_char) -> ValueRef;
fn LLVMBuildPointerCast(B: BuilderRef, Val: ValueRef, DestTy: TypeRef,
Name: *c_char) -> ValueRef;
fn LLVMBuildIntCast(B: BuilderRef, Val: ValueRef, DestTy: TypeRef,
unsafe fn LLVMBuildPointerCast(B: BuilderRef,
Val: ValueRef,
DestTy: TypeRef,
Name: *c_char)
-> ValueRef;
unsafe fn LLVMBuildIntCast(B: BuilderRef, Val: ValueRef, DestTy: TypeRef,
Name: *c_char) -> ValueRef;
fn LLVMBuildFPCast(B: BuilderRef, Val: ValueRef, DestTy: TypeRef,
unsafe fn LLVMBuildFPCast(B: BuilderRef, Val: ValueRef, DestTy: TypeRef,
Name: *c_char) -> ValueRef;
/* Comparisons */
fn LLVMBuildICmp(B: BuilderRef, Op: c_uint, LHS: ValueRef,
unsafe fn LLVMBuildICmp(B: BuilderRef, Op: c_uint, LHS: ValueRef,
RHS: ValueRef, Name: *c_char) -> ValueRef;
fn LLVMBuildFCmp(B: BuilderRef, Op: c_uint, LHS: ValueRef,
unsafe fn LLVMBuildFCmp(B: BuilderRef, Op: c_uint, LHS: ValueRef,
RHS: ValueRef, Name: *c_char) -> ValueRef;
/* Miscellaneous instructions */
fn LLVMBuildPhi(B: BuilderRef, Ty: TypeRef, Name: *c_char) -> ValueRef;
fn LLVMBuildCall(B: BuilderRef, Fn: ValueRef, Args: *ValueRef,
unsafe fn LLVMBuildPhi(B: BuilderRef,
Ty: TypeRef,
Name: *c_char)
-> ValueRef;
unsafe fn LLVMBuildCall(B: BuilderRef, Fn: ValueRef, Args: *ValueRef,
NumArgs: c_uint, Name: *c_char) -> ValueRef;
fn LLVMBuildSelect(B: BuilderRef, If: ValueRef, Then: ValueRef,
unsafe fn LLVMBuildSelect(B: BuilderRef, If: ValueRef, Then: ValueRef,
Else: ValueRef, Name: *c_char) -> ValueRef;
fn LLVMBuildVAArg(B: BuilderRef, list: ValueRef, Ty: TypeRef,
unsafe fn LLVMBuildVAArg(B: BuilderRef, list: ValueRef, Ty: TypeRef,
Name: *c_char)
-> ValueRef;
fn LLVMBuildExtractElement(B: BuilderRef, VecVal: ValueRef,
Index: ValueRef, Name: *c_char) -> ValueRef;
fn LLVMBuildInsertElement(B: BuilderRef, VecVal: ValueRef,
EltVal: ValueRef, Index: ValueRef,
Name: *c_char)
-> ValueRef;
fn LLVMBuildShuffleVector(B: BuilderRef, V1: ValueRef, V2: ValueRef,
Mask: ValueRef, Name: *c_char) -> ValueRef;
fn LLVMBuildExtractValue(B: BuilderRef, AggVal: ValueRef, Index: c_uint,
Name: *c_char) -> ValueRef;
fn LLVMBuildInsertValue(B: BuilderRef, AggVal: ValueRef, EltVal: ValueRef,
Index: c_uint, Name: *c_char) -> ValueRef;
unsafe fn LLVMBuildExtractElement(B: BuilderRef,
VecVal: ValueRef,
Index: ValueRef,
Name: *c_char)
-> ValueRef;
unsafe fn LLVMBuildInsertElement(B: BuilderRef,
VecVal: ValueRef,
EltVal: ValueRef,
Index: ValueRef,
Name: *c_char)
-> ValueRef;
unsafe fn LLVMBuildShuffleVector(B: BuilderRef,
V1: ValueRef,
V2: ValueRef,
Mask: ValueRef,
Name: *c_char)
-> ValueRef;
unsafe fn LLVMBuildExtractValue(B: BuilderRef,
AggVal: ValueRef,
Index: c_uint,
Name: *c_char)
-> ValueRef;
unsafe fn LLVMBuildInsertValue(B: BuilderRef,
AggVal: ValueRef,
EltVal: ValueRef,
Index: c_uint,
Name: *c_char)
-> ValueRef;
fn LLVMBuildIsNull(B: BuilderRef, Val: ValueRef,
Name: *c_char) -> ValueRef;
fn LLVMBuildIsNotNull(B: BuilderRef, Val: ValueRef, Name: *c_char) ->
ValueRef;
fn LLVMBuildPtrDiff(B: BuilderRef, LHS: ValueRef, RHS: ValueRef,
unsafe fn LLVMBuildIsNull(B: BuilderRef, Val: ValueRef, Name: *c_char)
-> ValueRef;
unsafe fn LLVMBuildIsNotNull(B: BuilderRef, Val: ValueRef, Name: *c_char)
-> ValueRef;
unsafe fn LLVMBuildPtrDiff(B: BuilderRef, LHS: ValueRef, RHS: ValueRef,
Name: *c_char) -> ValueRef;
/* Atomic Operations */
fn LLVMBuildAtomicCmpXchg(B: BuilderRef, LHS: ValueRef,
unsafe fn LLVMBuildAtomicCmpXchg(B: BuilderRef, LHS: ValueRef,
CMP: ValueRef, RHS: ValueRef,
++Order: AtomicOrdering) -> ValueRef;
fn LLVMBuildAtomicRMW(B: BuilderRef, ++Op: AtomicBinOp,
unsafe fn LLVMBuildAtomicRMW(B: BuilderRef, ++Op: AtomicBinOp,
LHS: ValueRef, RHS: ValueRef,
++Order: AtomicOrdering) -> ValueRef;
/* Selected entries from the downcasts. */
fn LLVMIsATerminatorInst(Inst: ValueRef) -> ValueRef;
unsafe fn LLVMIsATerminatorInst(Inst: ValueRef) -> ValueRef;
/** Writes a module to the specified path. Returns 0 on success. */
fn LLVMWriteBitcodeToFile(M: ModuleRef, Path: *c_char) -> c_int;
unsafe fn LLVMWriteBitcodeToFile(M: ModuleRef, Path: *c_char) -> c_int;
/** Creates target data from a target layout string. */
fn LLVMCreateTargetData(StringRep: *c_char) -> TargetDataRef;
unsafe fn LLVMCreateTargetData(StringRep: *c_char) -> TargetDataRef;
/** Adds the target data to the given pass manager. The pass manager
references the target data only weakly. */
fn LLVMAddTargetData(TD: TargetDataRef, PM: PassManagerRef);
unsafe fn LLVMAddTargetData(TD: TargetDataRef, PM: PassManagerRef);
/** Number of bytes clobbered when doing a Store to *T. */
fn LLVMStoreSizeOfType(TD: TargetDataRef, Ty: TypeRef) -> c_ulonglong;
unsafe fn LLVMStoreSizeOfType(TD: TargetDataRef, Ty: TypeRef)
-> c_ulonglong;
/** Number of bytes clobbered when doing a Store to *T. */
fn LLVMSizeOfTypeInBits(TD: TargetDataRef, Ty: TypeRef) -> c_ulonglong;
unsafe fn LLVMSizeOfTypeInBits(TD: TargetDataRef, Ty: TypeRef)
-> c_ulonglong;
/** Distance between successive elements in an array of T.
Includes ABI padding. */
fn LLVMABISizeOfType(TD: TargetDataRef, Ty: TypeRef) -> c_uint;
unsafe fn LLVMABISizeOfType(TD: TargetDataRef, Ty: TypeRef) -> c_uint;
/** Returns the preferred alignment of a type. */
fn LLVMPreferredAlignmentOfType(TD: TargetDataRef,
unsafe fn LLVMPreferredAlignmentOfType(TD: TargetDataRef,
Ty: TypeRef) -> c_uint;
/** Returns the minimum alignment of a type. */
fn LLVMABIAlignmentOfType(TD: TargetDataRef,
unsafe fn LLVMABIAlignmentOfType(TD: TargetDataRef,
Ty: TypeRef) -> c_uint;
/** Returns the minimum alignment of a type when part of a call frame. */
fn LLVMCallFrameAlignmentOfType(TD: TargetDataRef,
unsafe fn LLVMCallFrameAlignmentOfType(TD: TargetDataRef,
Ty: TypeRef) -> c_uint;
/** Disposes target data. */
fn LLVMDisposeTargetData(TD: TargetDataRef);
unsafe fn LLVMDisposeTargetData(TD: TargetDataRef);
/** Creates a pass manager. */
fn LLVMCreatePassManager() -> PassManagerRef;
unsafe fn LLVMCreatePassManager() -> PassManagerRef;
/** Disposes a pass manager. */
fn LLVMDisposePassManager(PM: PassManagerRef);
unsafe fn LLVMDisposePassManager(PM: PassManagerRef);
/** Runs a pass manager on a module. */
fn LLVMRunPassManager(PM: PassManagerRef, M: ModuleRef) -> Bool;
unsafe fn LLVMRunPassManager(PM: PassManagerRef, M: ModuleRef) -> Bool;
/** Adds a verification pass. */
fn LLVMAddVerifierPass(PM: PassManagerRef);
unsafe fn LLVMAddVerifierPass(PM: PassManagerRef);
fn LLVMAddGlobalOptimizerPass(PM: PassManagerRef);
fn LLVMAddIPSCCPPass(PM: PassManagerRef);
fn LLVMAddDeadArgEliminationPass(PM: PassManagerRef);
fn LLVMAddInstructionCombiningPass(PM: PassManagerRef);
fn LLVMAddCFGSimplificationPass(PM: PassManagerRef);
fn LLVMAddFunctionInliningPass(PM: PassManagerRef);
fn LLVMAddFunctionAttrsPass(PM: PassManagerRef);
fn LLVMAddScalarReplAggregatesPass(PM: PassManagerRef);
fn LLVMAddScalarReplAggregatesPassSSA(PM: PassManagerRef);
fn LLVMAddJumpThreadingPass(PM: PassManagerRef);
fn LLVMAddConstantPropagationPass(PM: PassManagerRef);
fn LLVMAddReassociatePass(PM: PassManagerRef);
fn LLVMAddLoopRotatePass(PM: PassManagerRef);
fn LLVMAddLICMPass(PM: PassManagerRef);
fn LLVMAddLoopUnswitchPass(PM: PassManagerRef);
fn LLVMAddLoopDeletionPass(PM: PassManagerRef);
fn LLVMAddLoopUnrollPass(PM: PassManagerRef);
fn LLVMAddGVNPass(PM: PassManagerRef);
fn LLVMAddMemCpyOptPass(PM: PassManagerRef);
fn LLVMAddSCCPPass(PM: PassManagerRef);
fn LLVMAddDeadStoreEliminationPass(PM: PassManagerRef);
fn LLVMAddStripDeadPrototypesPass(PM: PassManagerRef);
fn LLVMAddConstantMergePass(PM: PassManagerRef);
fn LLVMAddArgumentPromotionPass(PM: PassManagerRef);
fn LLVMAddTailCallEliminationPass(PM: PassManagerRef);
fn LLVMAddIndVarSimplifyPass(PM: PassManagerRef);
fn LLVMAddAggressiveDCEPass(PM: PassManagerRef);
fn LLVMAddGlobalDCEPass(PM: PassManagerRef);
fn LLVMAddCorrelatedValuePropagationPass(PM: PassManagerRef);
fn LLVMAddPruneEHPass(PM: PassManagerRef);
fn LLVMAddSimplifyLibCallsPass(PM: PassManagerRef);
fn LLVMAddLoopIdiomPass(PM: PassManagerRef);
fn LLVMAddEarlyCSEPass(PM: PassManagerRef);
fn LLVMAddTypeBasedAliasAnalysisPass(PM: PassManagerRef);
fn LLVMAddBasicAliasAnalysisPass(PM: PassManagerRef);
unsafe fn LLVMAddGlobalOptimizerPass(PM: PassManagerRef);
unsafe fn LLVMAddIPSCCPPass(PM: PassManagerRef);
unsafe fn LLVMAddDeadArgEliminationPass(PM: PassManagerRef);
unsafe fn LLVMAddInstructionCombiningPass(PM: PassManagerRef);
unsafe fn LLVMAddCFGSimplificationPass(PM: PassManagerRef);
unsafe fn LLVMAddFunctionInliningPass(PM: PassManagerRef);
unsafe fn LLVMAddFunctionAttrsPass(PM: PassManagerRef);
unsafe fn LLVMAddScalarReplAggregatesPass(PM: PassManagerRef);
unsafe fn LLVMAddScalarReplAggregatesPassSSA(PM: PassManagerRef);
unsafe fn LLVMAddJumpThreadingPass(PM: PassManagerRef);
unsafe fn LLVMAddConstantPropagationPass(PM: PassManagerRef);
unsafe fn LLVMAddReassociatePass(PM: PassManagerRef);
unsafe fn LLVMAddLoopRotatePass(PM: PassManagerRef);
unsafe fn LLVMAddLICMPass(PM: PassManagerRef);
unsafe fn LLVMAddLoopUnswitchPass(PM: PassManagerRef);
unsafe fn LLVMAddLoopDeletionPass(PM: PassManagerRef);
unsafe fn LLVMAddLoopUnrollPass(PM: PassManagerRef);
unsafe fn LLVMAddGVNPass(PM: PassManagerRef);
unsafe fn LLVMAddMemCpyOptPass(PM: PassManagerRef);
unsafe fn LLVMAddSCCPPass(PM: PassManagerRef);
unsafe fn LLVMAddDeadStoreEliminationPass(PM: PassManagerRef);
unsafe fn LLVMAddStripDeadPrototypesPass(PM: PassManagerRef);
unsafe fn LLVMAddConstantMergePass(PM: PassManagerRef);
unsafe fn LLVMAddArgumentPromotionPass(PM: PassManagerRef);
unsafe fn LLVMAddTailCallEliminationPass(PM: PassManagerRef);
unsafe fn LLVMAddIndVarSimplifyPass(PM: PassManagerRef);
unsafe fn LLVMAddAggressiveDCEPass(PM: PassManagerRef);
unsafe fn LLVMAddGlobalDCEPass(PM: PassManagerRef);
unsafe fn LLVMAddCorrelatedValuePropagationPass(PM: PassManagerRef);
unsafe fn LLVMAddPruneEHPass(PM: PassManagerRef);
unsafe fn LLVMAddSimplifyLibCallsPass(PM: PassManagerRef);
unsafe fn LLVMAddLoopIdiomPass(PM: PassManagerRef);
unsafe fn LLVMAddEarlyCSEPass(PM: PassManagerRef);
unsafe fn LLVMAddTypeBasedAliasAnalysisPass(PM: PassManagerRef);
unsafe fn LLVMAddBasicAliasAnalysisPass(PM: PassManagerRef);
fn LLVMPassManagerBuilderCreate() -> PassManagerBuilderRef;
fn LLVMPassManagerBuilderDispose(PMB: PassManagerBuilderRef);
fn LLVMPassManagerBuilderSetOptLevel(PMB: PassManagerBuilderRef,
unsafe fn LLVMPassManagerBuilderCreate() -> PassManagerBuilderRef;
unsafe fn LLVMPassManagerBuilderDispose(PMB: PassManagerBuilderRef);
unsafe fn LLVMPassManagerBuilderSetOptLevel(PMB: PassManagerBuilderRef,
OptimizationLevel: c_uint);
fn LLVMPassManagerBuilderSetSizeLevel(PMB: PassManagerBuilderRef,
unsafe fn LLVMPassManagerBuilderSetSizeLevel(PMB: PassManagerBuilderRef,
Value: Bool);
fn LLVMPassManagerBuilderSetDisableUnitAtATime(PMB: PassManagerBuilderRef,
Value: Bool);
fn LLVMPassManagerBuilderSetDisableUnrollLoops(PMB: PassManagerBuilderRef,
Value: Bool);
fn LLVMPassManagerBuilderSetDisableSimplifyLibCalls
unsafe fn LLVMPassManagerBuilderSetDisableUnitAtATime(
PMB: PassManagerBuilderRef, Value: Bool);
unsafe fn LLVMPassManagerBuilderSetDisableUnrollLoops(
PMB: PassManagerBuilderRef, Value: Bool);
unsafe fn LLVMPassManagerBuilderSetDisableSimplifyLibCalls
(PMB: PassManagerBuilderRef, Value: Bool);
fn LLVMPassManagerBuilderUseInlinerWithThreshold
unsafe fn LLVMPassManagerBuilderUseInlinerWithThreshold
(PMB: PassManagerBuilderRef, threshold: c_uint);
fn LLVMPassManagerBuilderPopulateModulePassManager
unsafe fn LLVMPassManagerBuilderPopulateModulePassManager
(PMB: PassManagerBuilderRef, PM: PassManagerRef);
fn LLVMPassManagerBuilderPopulateFunctionPassManager
unsafe fn LLVMPassManagerBuilderPopulateFunctionPassManager
(PMB: PassManagerBuilderRef, PM: PassManagerRef);
/** Destroys a memory buffer. */
fn LLVMDisposeMemoryBuffer(MemBuf: MemoryBufferRef);
unsafe fn LLVMDisposeMemoryBuffer(MemBuf: MemoryBufferRef);
/* Stuff that's in rustllvm/ because it's not upstream yet. */
/** Opens an object file. */
fn LLVMCreateObjectFile(MemBuf: MemoryBufferRef) -> ObjectFileRef;
unsafe fn LLVMCreateObjectFile(MemBuf: MemoryBufferRef) -> ObjectFileRef;
/** Closes an object file. */
fn LLVMDisposeObjectFile(ObjFile: ObjectFileRef);
unsafe fn LLVMDisposeObjectFile(ObjFile: ObjectFileRef);
/** Enumerates the sections in an object file. */
fn LLVMGetSections(ObjFile: ObjectFileRef) -> SectionIteratorRef;
unsafe fn LLVMGetSections(ObjFile: ObjectFileRef) -> SectionIteratorRef;
/** Destroys a section iterator. */
fn LLVMDisposeSectionIterator(SI: SectionIteratorRef);
unsafe fn LLVMDisposeSectionIterator(SI: SectionIteratorRef);
/** Returns true if the section iterator is at the end of the section
list: */
fn LLVMIsSectionIteratorAtEnd(ObjFile: ObjectFileRef,
unsafe fn LLVMIsSectionIteratorAtEnd(ObjFile: ObjectFileRef,
SI: SectionIteratorRef) -> Bool;
/** Moves the section iterator to point to the next section. */
fn LLVMMoveToNextSection(SI: SectionIteratorRef);
unsafe fn LLVMMoveToNextSection(SI: SectionIteratorRef);
/** Returns the current section name. */
fn LLVMGetSectionName(SI: SectionIteratorRef) -> *c_char;
unsafe fn LLVMGetSectionName(SI: SectionIteratorRef) -> *c_char;
/** Returns the current section size. */
fn LLVMGetSectionSize(SI: SectionIteratorRef) -> c_ulonglong;
unsafe fn LLVMGetSectionSize(SI: SectionIteratorRef) -> c_ulonglong;
/** Returns the current section contents as a string buffer. */
fn LLVMGetSectionContents(SI: SectionIteratorRef) -> *c_char;
unsafe fn LLVMGetSectionContents(SI: SectionIteratorRef) -> *c_char;
/** Reads the given file and returns it as a memory buffer. Use
LLVMDisposeMemoryBuffer() to get rid of it. */
fn LLVMRustCreateMemoryBufferWithContentsOfFile(Path: *c_char) ->
unsafe fn LLVMRustCreateMemoryBufferWithContentsOfFile(Path: *c_char) ->
MemoryBufferRef;
fn LLVMRustWriteOutputFile(PM: PassManagerRef, M: ModuleRef,
unsafe fn LLVMRustWriteOutputFile(PM: PassManagerRef, M: ModuleRef,
Triple: *c_char,
// FIXME: When #2334 is fixed, change
// c_uint to FileType
@@ -1014,57 +1190,63 @@ fn LLVMRustWriteOutputFile(PM: PassManagerRef, M: ModuleRef,
/** Returns a string describing the last error caused by an LLVMRust*
call. */
fn LLVMRustGetLastError() -> *c_char;
unsafe fn LLVMRustGetLastError() -> *c_char;
/** Prepare the JIT. Returns a memory manager that can load crates. */
fn LLVMRustPrepareJIT(__morestack: *()) -> *();
unsafe fn LLVMRustPrepareJIT(__morestack: *()) -> *();
/** Load a crate into the memory manager. */
fn LLVMRustLoadCrate(MM: *(),
unsafe fn LLVMRustLoadCrate(MM: *(),
Filename: *c_char) -> bool;
/** Execute the JIT engine. */
fn LLVMRustExecuteJIT(MM: *(),
unsafe fn LLVMRustExecuteJIT(MM: *(),
PM: PassManagerRef,
M: ModuleRef,
OptLevel: c_int,
EnableSegmentedStacks: bool) -> *();
/** Parses the bitcode in the given memory buffer. */
fn LLVMRustParseBitcode(MemBuf: MemoryBufferRef) -> ModuleRef;
unsafe fn LLVMRustParseBitcode(MemBuf: MemoryBufferRef) -> ModuleRef;
/** Parses LLVM asm in the given file */
fn LLVMRustParseAssemblyFile(Filename: *c_char) -> ModuleRef;
unsafe fn LLVMRustParseAssemblyFile(Filename: *c_char) -> ModuleRef;
fn LLVMRustAddPrintModulePass(PM: PassManagerRef, M: ModuleRef,
unsafe fn LLVMRustAddPrintModulePass(PM: PassManagerRef, M: ModuleRef,
Output: *c_char);
/** Turn on LLVM pass-timing. */
fn LLVMRustEnableTimePasses();
unsafe fn LLVMRustEnableTimePasses();
/** Print the pass timings since static dtors aren't picking them up. */
fn LLVMRustPrintPassTimings();
unsafe fn LLVMRustPrintPassTimings();
fn LLVMStructCreateNamed(C: ContextRef, Name: *c_char) -> TypeRef;
unsafe fn LLVMStructCreateNamed(C: ContextRef, Name: *c_char) -> TypeRef;
fn LLVMStructSetBody(StructTy: TypeRef, ElementTypes: *TypeRef,
unsafe fn LLVMStructSetBody(StructTy: TypeRef, ElementTypes: *TypeRef,
ElementCount: c_uint, Packed: Bool);
fn LLVMConstNamedStruct(S: TypeRef, ConstantVals: *ValueRef,
unsafe fn LLVMConstNamedStruct(S: TypeRef, ConstantVals: *ValueRef,
Count: c_uint) -> ValueRef;
/** Enables LLVM debug output. */
fn LLVMSetDebug(Enabled: c_int);
unsafe fn LLVMSetDebug(Enabled: c_int);
}
fn SetInstructionCallConv(Instr: ValueRef, CC: CallConv) {
llvm::LLVMSetInstructionCallConv(Instr, CC as c_uint);
unsafe {
llvm::LLVMSetInstructionCallConv(Instr, CC as c_uint);
}
}
fn SetFunctionCallConv(Fn: ValueRef, CC: CallConv) {
llvm::LLVMSetFunctionCallConv(Fn, CC as c_uint);
unsafe {
llvm::LLVMSetFunctionCallConv(Fn, CC as c_uint);
}
}
fn SetLinkage(Global: ValueRef, Link: Linkage) {
llvm::LLVMSetLinkage(Global, Link as c_uint);
unsafe {
llvm::LLVMSetLinkage(Global, Link as c_uint);
}
}
/* Memory-managed object interface to type handles. */
@@ -1097,108 +1279,117 @@ fn type_to_str(names: type_names, ty: TypeRef) -> ~str {
fn type_to_str_inner(names: type_names, +outer0: ~[TypeRef], ty: TypeRef) ->
~str {
match type_has_name(names, ty) {
option::Some(ref n) => return (/*bad*/copy *n),
_ => {}
}
// XXX: Bad copy.
let outer = vec::append_one(copy outer0, ty);
let kind = llvm::LLVMGetTypeKind(ty);
fn tys_str(names: type_names, outer: ~[TypeRef],
tys: ~[TypeRef]) -> ~str {
let mut s: ~str = ~"";
let mut first: bool = true;
for tys.each |t| {
if first { first = false; } else { s += ~", "; }
s += type_to_str_inner(names, outer, *t);
unsafe {
match type_has_name(names, ty) {
option::Some(ref n) => return (/*bad*/copy *n),
_ => {}
}
return s;
}
match kind {
Void => return ~"Void",
Half => return ~"Half",
Float => return ~"Float",
Double => return ~"Double",
X86_FP80 => return ~"X86_FP80",
FP128 => return ~"FP128",
PPC_FP128 => return ~"PPC_FP128",
Label => return ~"Label",
Integer => {
return ~"i" + int::str(llvm::LLVMGetIntTypeWidth(ty) as int);
}
Function => {
let mut s = ~"fn(";
let out_ty: TypeRef = llvm::LLVMGetReturnType(ty);
let n_args = llvm::LLVMCountParamTypes(ty) as uint;
let args = vec::from_elem(n_args, 0 as TypeRef);
unsafe {
llvm::LLVMGetParamTypes(ty, vec::raw::to_ptr(args));
}
s += tys_str(names, outer, args);
s += ~") -> ";
s += type_to_str_inner(names, outer, out_ty);
return s;
}
Struct => {
let mut s: ~str = ~"{";
let n_elts = llvm::LLVMCountStructElementTypes(ty) as uint;
let mut elts = vec::from_elem(n_elts, 0 as TypeRef);
llvm::LLVMGetStructElementTypes(ty,
ptr::to_mut_unsafe_ptr(&mut elts[0]));
s += tys_str(names, outer, elts);
s += ~"}";
return s;
}
Array => {
let el_ty = llvm::LLVMGetElementType(ty);
return ~"[" + type_to_str_inner(names, outer, el_ty) + ~" x " +
uint::str(llvm::LLVMGetArrayLength(ty) as uint) + ~"]";
}
Pointer => {
let mut i: uint = 0u;
for outer0.each |tout| {
i += 1u;
if *tout as int == ty as int {
let n: uint = vec::len::<TypeRef>(outer0) - i;
return ~"*\\" + int::str(n as int);
// XXX: Bad copy.
let outer = vec::append_one(copy outer0, ty);
let kind = llvm::LLVMGetTypeKind(ty);
fn tys_str(names: type_names, outer: ~[TypeRef],
tys: ~[TypeRef]) -> ~str {
let mut s: ~str = ~"";
let mut first: bool = true;
for tys.each |t| {
if first { first = false; } else { s += ~", "; }
s += type_to_str_inner(names, outer, *t);
}
return s;
}
let addrstr = {
let addrspace = llvm::LLVMGetPointerAddressSpace(ty) as uint;
if addrspace == 0u {
~""
} else {
fmt!("addrspace(%u)", addrspace)
match kind {
Void => return ~"Void",
Half => return ~"Half",
Float => return ~"Float",
Double => return ~"Double",
X86_FP80 => return ~"X86_FP80",
FP128 => return ~"FP128",
PPC_FP128 => return ~"PPC_FP128",
Label => return ~"Label",
Integer => {
return ~"i" + int::str(llvm::LLVMGetIntTypeWidth(ty) as int);
}
Function => {
let mut s = ~"fn(";
let out_ty: TypeRef = llvm::LLVMGetReturnType(ty);
let n_args = llvm::LLVMCountParamTypes(ty) as uint;
let args = vec::from_elem(n_args, 0 as TypeRef);
unsafe {
llvm::LLVMGetParamTypes(ty, vec::raw::to_ptr(args));
}
};
return addrstr + ~"*" +
type_to_str_inner(names, outer, llvm::LLVMGetElementType(ty));
}
Vector => return ~"Vector",
Metadata => return ~"Metadata",
X86_MMX => return ~"X86_MMAX"
s += tys_str(names, outer, args);
s += ~") -> ";
s += type_to_str_inner(names, outer, out_ty);
return s;
}
Struct => {
let mut s: ~str = ~"{";
let n_elts = llvm::LLVMCountStructElementTypes(ty) as uint;
let mut elts = vec::from_elem(n_elts, 0 as TypeRef);
llvm::LLVMGetStructElementTypes(ty,
ptr::to_mut_unsafe_ptr(
&mut elts[0]));
s += tys_str(names, outer, elts);
s += ~"}";
return s;
}
Array => {
let el_ty = llvm::LLVMGetElementType(ty);
return ~"[" + type_to_str_inner(names, outer, el_ty) + ~" x " +
uint::str(llvm::LLVMGetArrayLength(ty) as uint) + ~"]";
}
Pointer => {
let mut i: uint = 0u;
for outer0.each |tout| {
i += 1u;
if *tout as int == ty as int {
let n: uint = vec::len::<TypeRef>(outer0) - i;
return ~"*\\" + int::str(n as int);
}
}
let addrstr = {
let addrspace = llvm::LLVMGetPointerAddressSpace(ty) as uint;
if addrspace == 0u {
~""
} else {
fmt!("addrspace(%u)", addrspace)
}
};
return addrstr + ~"*" +
type_to_str_inner(names,
outer,
llvm::LLVMGetElementType(ty));
}
Vector => return ~"Vector",
Metadata => return ~"Metadata",
X86_MMX => return ~"X86_MMAX"
}
}
}
fn float_width(llt: TypeRef) -> uint {
return match llvm::LLVMGetTypeKind(llt) as int {
1 => 32u,
2 => 64u,
3 => 80u,
4 | 5 => 128u,
_ => fail ~"llvm_float_width called on a non-float type"
};
unsafe {
return match llvm::LLVMGetTypeKind(llt) as int {
1 => 32u,
2 => 64u,
3 => 80u,
4 | 5 => 128u,
_ => fail ~"llvm_float_width called on a non-float type"
};
}
}
fn fn_ty_param_tys(fn_ty: TypeRef) -> ~[TypeRef] unsafe {
let args = vec::from_elem(llvm::LLVMCountParamTypes(fn_ty) as uint,
0 as TypeRef);
llvm::LLVMGetParamTypes(fn_ty, vec::raw::to_ptr(args));
return args;
unsafe {
let args = vec::from_elem(llvm::LLVMCountParamTypes(fn_ty) as uint,
0 as TypeRef);
llvm::LLVMGetParamTypes(fn_ty, vec::raw::to_ptr(args));
return args;
}
}
fn struct_element_types(struct_ty: TypeRef) -> ~[TypeRef] {
@@ -1218,7 +1409,11 @@ fn struct_element_types(struct_ty: TypeRef) -> ~[TypeRef] {
struct target_data_res {
TD: TargetDataRef,
drop { llvm::LLVMDisposeTargetData(self.TD); }
drop {
unsafe {
llvm::LLVMDisposeTargetData(self.TD);
}
}
}
fn target_data_res(TD: TargetDataRef) -> target_data_res {
@@ -1231,7 +1426,9 @@ fn target_data_res(TD: TargetDataRef) -> target_data_res {
fn mk_target_data(string_rep: ~str) -> target_data {
let lltd =
str::as_c_str(string_rep, |buf| llvm::LLVMCreateTargetData(buf) );
str::as_c_str(string_rep, |buf| unsafe {
llvm::LLVMCreateTargetData(buf)
});
return {lltd: lltd, dtor: @target_data_res(lltd)};
}
@@ -1239,7 +1436,11 @@ fn mk_target_data(string_rep: ~str) -> target_data {
struct pass_manager_res {
PM: PassManagerRef,
drop { llvm::LLVMDisposePassManager(self.PM); }
drop {
unsafe {
llvm::LLVMDisposePassManager(self.PM);
}
}
}
fn pass_manager_res(PM: PassManagerRef) -> pass_manager_res {
@@ -1251,15 +1452,21 @@ fn pass_manager_res(PM: PassManagerRef) -> pass_manager_res {
type pass_manager = {llpm: PassManagerRef, dtor: @pass_manager_res};
fn mk_pass_manager() -> pass_manager {
let llpm = llvm::LLVMCreatePassManager();
return {llpm: llpm, dtor: @pass_manager_res(llpm)};
unsafe {
let llpm = llvm::LLVMCreatePassManager();
return {llpm: llpm, dtor: @pass_manager_res(llpm)};
}
}
/* Memory-managed interface to object files. */
struct object_file_res {
ObjectFile: ObjectFileRef,
drop { llvm::LLVMDisposeObjectFile(self.ObjectFile); }
drop {
unsafe {
llvm::LLVMDisposeObjectFile(self.ObjectFile);
}
}
}
fn object_file_res(ObjFile: ObjectFileRef) -> object_file_res {
@@ -1271,16 +1478,22 @@ fn object_file_res(ObjFile: ObjectFileRef) -> object_file_res {
type object_file = {llof: ObjectFileRef, dtor: @object_file_res};
fn mk_object_file(llmb: MemoryBufferRef) -> Option<object_file> {
let llof = llvm::LLVMCreateObjectFile(llmb);
if llof as int == 0 { return option::None::<object_file>; }
return option::Some({llof: llof, dtor: @object_file_res(llof)});
unsafe {
let llof = llvm::LLVMCreateObjectFile(llmb);
if llof as int == 0 { return option::None::<object_file>; }
return option::Some({llof: llof, dtor: @object_file_res(llof)});
}
}
/* Memory-managed interface to section iterators. */
struct section_iter_res {
SI: SectionIteratorRef,
drop { llvm::LLVMDisposeSectionIterator(self.SI); }
drop {
unsafe {
llvm::LLVMDisposeSectionIterator(self.SI);
}
}
}
fn section_iter_res(SI: SectionIteratorRef) -> section_iter_res {
@@ -1292,8 +1505,10 @@ fn section_iter_res(SI: SectionIteratorRef) -> section_iter_res {
type section_iter = {llsi: SectionIteratorRef, dtor: @section_iter_res};
fn mk_section_iter(llof: ObjectFileRef) -> section_iter {
let llsi = llvm::LLVMGetSections(llof);
return {llsi: llsi, dtor: @section_iter_res(llsi)};
unsafe {
let llsi = llvm::LLVMGetSections(llof);
return {llsi: llsi, dtor: @section_iter_res(llsi)};
}
}
//
+2
View File
@@ -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(
+362 -251
View File
@@ -138,9 +138,13 @@ fn log_fn_time(ccx: @crate_ctxt, +name: ~str, start: time::Timespec,
fn decl_fn(llmod: ModuleRef, name: ~str, cc: lib::llvm::CallConv,
llty: TypeRef) -> ValueRef {
let llfn: ValueRef = str::as_c_str(name, |buf| {
llvm::LLVMGetOrInsertFunction(llmod, buf, llty)
unsafe {
llvm::LLVMGetOrInsertFunction(llmod, buf, llty)
}
});
lib::llvm::SetFunctionCallConv(llfn, cc);
unsafe {
lib::llvm::SetFunctionCallConv(llfn, cc);
}
return llfn;
}
@@ -172,11 +176,15 @@ fn get_extern_fn(externs: HashMap<~str, ValueRef>,
fn get_extern_const(externs: HashMap<~str, ValueRef>, llmod: ModuleRef,
+name: ~str, ty: TypeRef) -> ValueRef {
// XXX: Bad copy.
if externs.contains_key(copy name) { return externs.get(name); }
let c = str::as_c_str(name, |buf| llvm::LLVMAddGlobal(llmod, ty, buf));
externs.insert(name, c);
return c;
unsafe {
// XXX: Bad copy.
if externs.contains_key(copy name) { return externs.get(name); }
let c = str::as_c_str(name, |buf| {
llvm::LLVMAddGlobal(llmod, ty, buf)
});
externs.insert(name, c);
return c;
}
}
fn get_simple_extern_fn(cx: block,
@@ -314,12 +322,14 @@ fn malloc_raw_dyn(bcx: block,
* wrong address space and thus be the wrong type.
*/
fn non_gc_box_cast(bcx: block, val: ValueRef) -> ValueRef {
debug!("non_gc_box_cast");
add_comment(bcx, ~"non_gc_box_cast");
assert(llvm::LLVMGetPointerAddressSpace(val_ty(val)) == gc_box_addrspace
|| bcx.unreachable);
let non_gc_t = T_ptr(llvm::LLVMGetElementType(val_ty(val)));
PointerCast(bcx, val, non_gc_t)
unsafe {
debug!("non_gc_box_cast");
add_comment(bcx, ~"non_gc_box_cast");
assert(llvm::LLVMGetPointerAddressSpace(val_ty(val)) ==
gc_box_addrspace || bcx.unreachable);
let non_gc_t = T_ptr(llvm::LLVMGetElementType(val_ty(val)));
PointerCast(bcx, val, non_gc_t)
}
}
// malloc_raw: expects an unboxed type and returns a pointer to
@@ -373,25 +383,36 @@ fn get_tydesc(ccx: @crate_ctxt, t: ty::t) -> @tydesc_info {
}
fn set_no_inline(f: ValueRef) {
llvm::LLVMAddFunctionAttr(f, lib::llvm::NoInlineAttribute as c_ulonglong,
0u as c_ulonglong);
unsafe {
llvm::LLVMAddFunctionAttr(f,
lib::llvm::NoInlineAttribute as c_ulonglong,
0u as c_ulonglong);
}
}
fn set_no_unwind(f: ValueRef) {
llvm::LLVMAddFunctionAttr(f, lib::llvm::NoUnwindAttribute as c_ulonglong,
0u as c_ulonglong);
unsafe {
llvm::LLVMAddFunctionAttr(f,
lib::llvm::NoUnwindAttribute as c_ulonglong,
0u as c_ulonglong);
}
}
// Tell LLVM to emit the information necessary to unwind the stack for the
// function f.
fn set_uwtable(f: ValueRef) {
llvm::LLVMAddFunctionAttr(f, lib::llvm::UWTableAttribute as c_ulonglong,
0u as c_ulonglong);
unsafe {
llvm::LLVMAddFunctionAttr(f,
lib::llvm::UWTableAttribute as c_ulonglong,
0u as c_ulonglong);
}
}
fn set_inline_hint(f: ValueRef) {
llvm::LLVMAddFunctionAttr(f, lib::llvm::InlineHintAttribute
as c_ulonglong, 0u as c_ulonglong);
unsafe {
llvm::LLVMAddFunctionAttr(f, lib::llvm::InlineHintAttribute
as c_ulonglong, 0u as c_ulonglong);
}
}
fn set_inline_hint_if_appr(attrs: ~[ast::attribute],
@@ -405,12 +426,16 @@ fn set_inline_hint_if_appr(attrs: ~[ast::attribute],
}
fn set_always_inline(f: ValueRef) {
llvm::LLVMAddFunctionAttr(f, lib::llvm::AlwaysInlineAttribute
as c_ulonglong, 0u as c_ulonglong);
unsafe {
llvm::LLVMAddFunctionAttr(f, lib::llvm::AlwaysInlineAttribute
as c_ulonglong, 0u as c_ulonglong);
}
}
fn set_custom_stack_growth_fn(f: ValueRef) {
llvm::LLVMAddFunctionAttr(f, 0u as c_ulonglong, 1u as c_ulonglong);
unsafe {
llvm::LLVMAddFunctionAttr(f, 0u as c_ulonglong, 1u as c_ulonglong);
}
}
fn set_glue_inlining(f: ValueRef, t: ty::t) {
@@ -456,7 +481,11 @@ fn get_res_dtor(ccx: @crate_ctxt, did: ast::def_id,
// Structural comparison: a rather involved form of glue.
fn maybe_name_value(cx: @crate_ctxt, v: ValueRef, s: ~str) {
if cx.sess.opts.save_temps {
let _: () = str::as_c_str(s, |buf| llvm::LLVMSetValueName(v, buf));
let _: () = str::as_c_str(s, |buf| {
unsafe {
llvm::LLVMSetValueName(v, buf)
}
});
}
}
@@ -670,8 +699,11 @@ fn cast_shift_expr_rhs(cx: block, op: ast::binop,
fn cast_shift_const_rhs(op: ast::binop,
lhs: ValueRef, rhs: ValueRef) -> ValueRef {
cast_shift_rhs(op, lhs, rhs,
llvm::LLVMConstTrunc, llvm::LLVMConstZExt)
unsafe {
cast_shift_rhs(op, lhs, rhs,
|a, b| unsafe { llvm::LLVMConstTrunc(a, b) },
|a, b| unsafe { llvm::LLVMConstZExt(a, b) })
}
}
fn cast_shift_rhs(op: ast::binop,
@@ -680,22 +712,24 @@ fn cast_shift_rhs(op: ast::binop,
zext: fn(ValueRef, TypeRef) -> ValueRef
) -> ValueRef {
// Shifts may have any size int on the rhs
if ast_util::is_shift_binop(op) {
let rhs_llty = val_ty(rhs);
let lhs_llty = val_ty(lhs);
let rhs_sz = llvm::LLVMGetIntTypeWidth(rhs_llty);
let lhs_sz = llvm::LLVMGetIntTypeWidth(lhs_llty);
if lhs_sz < rhs_sz {
trunc(rhs, lhs_llty)
} else if lhs_sz > rhs_sz {
// FIXME (#1877: If shifting by negative
// values becomes not undefined then this is wrong.
zext(rhs, lhs_llty)
unsafe {
if ast_util::is_shift_binop(op) {
let rhs_llty = val_ty(rhs);
let lhs_llty = val_ty(lhs);
let rhs_sz = llvm::LLVMGetIntTypeWidth(rhs_llty);
let lhs_sz = llvm::LLVMGetIntTypeWidth(lhs_llty);
if lhs_sz < rhs_sz {
trunc(rhs, lhs_llty)
} else if lhs_sz > rhs_sz {
// FIXME (#1877: If shifting by negative
// values becomes not undefined then this is wrong.
zext(rhs, lhs_llty)
} else {
rhs
}
} else {
rhs
}
} else {
rhs
}
}
@@ -746,21 +780,23 @@ fn trans_external_path(ccx: @crate_ctxt, did: ast::def_id, t: ty::t)
}
fn lookup_discriminant(ccx: @crate_ctxt, vid: ast::def_id) -> ValueRef {
let _icx = ccx.insn_ctxt("lookup_discriminant");
match ccx.discrims.find(vid) {
None => {
// It's an external discriminant that we haven't seen yet.
assert (vid.crate != ast::local_crate);
let sym = csearch::get_symbol(ccx.sess.cstore, vid);
let gvar = str::as_c_str(sym, |buf| {
llvm::LLVMAddGlobal(ccx.llmod, ccx.int_type, buf)
});
lib::llvm::SetLinkage(gvar, lib::llvm::ExternalLinkage);
llvm::LLVMSetGlobalConstant(gvar, True);
ccx.discrims.insert(vid, gvar);
return gvar;
}
Some(llval) => return llval,
unsafe {
let _icx = ccx.insn_ctxt("lookup_discriminant");
match ccx.discrims.find(vid) {
None => {
// It's an external discriminant that we haven't seen yet.
assert (vid.crate != ast::local_crate);
let sym = csearch::get_symbol(ccx.sess.cstore, vid);
let gvar = str::as_c_str(sym, |buf| {
llvm::LLVMAddGlobal(ccx.llmod, ccx.int_type, buf)
});
lib::llvm::SetLinkage(gvar, lib::llvm::ExternalLinkage);
llvm::LLVMSetGlobalConstant(gvar, True);
ccx.discrims.insert(vid, gvar);
return gvar;
}
Some(llval) => return llval,
}
}
}
@@ -1094,15 +1130,24 @@ fn new_block(cx: fn_ctxt, parent: Option<block>, +kind: block_kind,
let s = if cx.ccx.sess.opts.save_temps || cx.ccx.sess.opts.debuginfo {
(cx.ccx.names)(name)
} else { special_idents::invalid };
let llbb: BasicBlockRef = str::as_c_str(cx.ccx.sess.str_of(s), |buf| {
llvm::LLVMAppendBasicBlock(cx.llfn, buf)
});
let bcx = mk_block(llbb, parent, move kind, is_lpad, opt_node_info, cx);
do option::iter(&parent) |cx| {
if cx.unreachable { Unreachable(bcx); }
} else {
special_idents::invalid
};
return bcx;
unsafe {
let llbb: BasicBlockRef = str::as_c_str(cx.ccx.sess.str_of(s), |buf| {
llvm::LLVMAppendBasicBlock(cx.llfn, buf)
});
let bcx = mk_block(llbb,
parent,
move kind,
is_lpad,
opt_node_info,
cx);
do option::iter(&parent) |cx| {
if cx.unreachable { Unreachable(bcx); }
};
return bcx;
}
}
fn simple_block_scope() -> block_kind {
@@ -1317,7 +1362,9 @@ fn alloc_local(cx: block, local: @ast::local) -> block {
if cx.sess().opts.debuginfo {
do option::iter(&simple_name) |name| {
str::as_c_str(cx.ccx().sess.str_of(*name), |buf| {
llvm::LLVMSetValueName(val, buf)
unsafe {
llvm::LLVMSetValueName(val, buf)
}
});
}
}
@@ -1424,7 +1471,11 @@ fn alloca_zeroed(cx: block, t: TypeRef) -> ValueRef {
fn alloca_maybe_zeroed(cx: block, t: TypeRef, zero: bool) -> ValueRef {
let _icx = cx.insn_ctxt("alloca");
if cx.unreachable { return llvm::LLVMGetUndef(t); }
if cx.unreachable {
unsafe {
return llvm::LLVMGetUndef(t);
}
}
let initcx = base::raw_block(cx.fcx, false, cx.fcx.llstaticallocas);
let p = Alloca(initcx, t);
if zero { memzero(initcx, p, t); }
@@ -1433,7 +1484,11 @@ fn alloca_maybe_zeroed(cx: block, t: TypeRef, zero: bool) -> ValueRef {
fn arrayalloca(cx: block, t: TypeRef, v: ValueRef) -> ValueRef {
let _icx = cx.insn_ctxt("arrayalloca");
if cx.unreachable { return llvm::LLVMGetUndef(t); }
if cx.unreachable {
unsafe {
return llvm::LLVMGetUndef(t);
}
}
return ArrayAlloca(
base::raw_block(cx.fcx, false, cx.fcx.llstaticallocas), t, v);
}
@@ -1441,10 +1496,12 @@ fn arrayalloca(cx: block, t: TypeRef, v: ValueRef) -> ValueRef {
// Creates the standard set of basic blocks for a function
fn mk_standard_basic_blocks(llfn: ValueRef) ->
{sa: BasicBlockRef, rt: BasicBlockRef} {
{sa: str::as_c_str(~"static_allocas",
|buf| llvm::LLVMAppendBasicBlock(llfn, buf)),
rt: str::as_c_str(~"return",
|buf| llvm::LLVMAppendBasicBlock(llfn, buf))}
unsafe {
{sa: str::as_c_str(~"static_allocas",
|buf| llvm::LLVMAppendBasicBlock(llfn, buf)),
rt: str::as_c_str(~"return",
|buf| llvm::LLVMAppendBasicBlock(llfn, buf))}
}
}
@@ -1464,8 +1521,8 @@ fn new_fn_ctxt_w_id(ccx: @crate_ctxt,
let llbbs = mk_standard_basic_blocks(llfndecl);
return @fn_ctxt_ {
llfn: llfndecl,
llenv: llvm::LLVMGetParam(llfndecl, 1u as c_uint),
llretptr: llvm::LLVMGetParam(llfndecl, 0u as c_uint),
llenv: unsafe { llvm::LLVMGetParam(llfndecl, 1u as c_uint) },
llretptr: unsafe { llvm::LLVMGetParam(llfndecl, 0u as c_uint) },
mut llstaticallocas: llbbs.sa,
mut llloadenv: None,
mut llreturn: llbbs.rt,
@@ -1532,8 +1589,10 @@ fn create_llargs_for_fn_args(cx: fn_ctxt,
// Return an array containing the ValueRefs that we get from
// llvm::LLVMGetParam for each argument.
vec::from_fn(args.len(), |i| {
let arg_n = first_real_arg + i;
llvm::LLVMGetParam(cx.llfn, arg_n as c_uint)
unsafe {
let arg_n = first_real_arg + i;
llvm::LLVMGetParam(cx.llfn, arg_n as c_uint)
}
})
}
@@ -1664,7 +1723,9 @@ fn trans_closure(ccx: @crate_ctxt,
// Set GC for function.
if ccx.sess.opts.gc {
do str::as_c_str("generic") |strategy| {
llvm::LLVMSetGC(fcx.llfn, strategy);
unsafe {
llvm::LLVMSetGC(fcx.llfn, strategy);
}
}
ccx.uses_gc = true;
}
@@ -2085,8 +2146,8 @@ fn create_main(ccx: @crate_ctxt, main_llfn: ValueRef) -> ValueRef {
let lltop = bcx.llbb;
// Call main.
let lloutputarg = llvm::LLVMGetParam(llfdecl, 0 as c_uint);
let llenvarg = llvm::LLVMGetParam(llfdecl, 1 as c_uint);
let lloutputarg = unsafe { llvm::LLVMGetParam(llfdecl, 0 as c_uint) };
let llenvarg = unsafe { llvm::LLVMGetParam(llfdecl, 1 as c_uint) };
let mut args = ~[lloutputarg, llenvarg];
Call(bcx, main_llfn, args);
@@ -2103,22 +2164,34 @@ fn create_entry_fn(ccx: @crate_ctxt, rust_main: ValueRef) {
let llfty = T_fn(~[ccx.int_type, ccx.int_type], ccx.int_type);
let llfn = decl_cdecl_fn(ccx.llmod, main_name(), llfty);
let llbb = str::as_c_str(~"top", |buf| {
llvm::LLVMAppendBasicBlock(llfn, buf)
unsafe {
llvm::LLVMAppendBasicBlock(llfn, buf)
}
});
let bld = ccx.builder.B;
llvm::LLVMPositionBuilderAtEnd(bld, llbb);
unsafe {
llvm::LLVMPositionBuilderAtEnd(bld, llbb);
}
let crate_map = ccx.crate_map;
let start_ty = T_fn(~[val_ty(rust_main), ccx.int_type, ccx.int_type,
val_ty(crate_map)], ccx.int_type);
let start = decl_cdecl_fn(ccx.llmod, ~"rust_start", start_ty);
let args = ~[rust_main, llvm::LLVMGetParam(llfn, 0 as c_uint),
llvm::LLVMGetParam(llfn, 1 as c_uint), crate_map];
let args = unsafe {
~[
rust_main,
llvm::LLVMGetParam(llfn, 0 as c_uint),
llvm::LLVMGetParam(llfn, 1 as c_uint),
crate_map
]
};
let result = unsafe {
llvm::LLVMBuildCall(bld, start, vec::raw::to_ptr(args),
args.len() as c_uint, noname())
};
llvm::LLVMBuildRet(bld, result);
unsafe {
llvm::LLVMBuildRet(bld, result);
}
}
}
@@ -2199,7 +2272,9 @@ fn get_item_val(ccx: @crate_ctxt, id: ast::node_id) -> ValueRef {
let typ = ty::node_id_to_type(ccx.tcx, i.id);
let s = mangle_exported_name(ccx, my_path, typ);
let g = str::as_c_str(s, |buf| {
llvm::LLVMAddGlobal(ccx.llmod, type_of(ccx, typ), buf)
unsafe {
llvm::LLVMAddGlobal(ccx.llmod, type_of(ccx, typ), buf)
}
});
ccx.item_symbols.insert(i.id, s);
g
@@ -2246,7 +2321,11 @@ fn get_item_val(ccx: @crate_ctxt, id: ast::node_id) -> ValueRef {
let typ = ty::node_id_to_type(ccx.tcx, ni.id);
let ident = ccx.sess.parse_sess.interner.get(ni.ident);
let g = do str::as_c_str(*ident) |buf| {
llvm::LLVMAddGlobal(ccx.llmod, type_of(ccx, typ), buf)
unsafe {
llvm::LLVMAddGlobal(ccx.llmod,
type_of(ccx, typ),
buf)
}
};
g
}
@@ -2262,9 +2341,13 @@ fn get_item_val(ccx: @crate_ctxt, id: ast::node_id) -> ValueRef {
let class_ty = ty::lookup_item_type(tcx, parent_id).ty;
// This code shouldn't be reached if the class is generic
assert !ty::type_has_params(class_ty);
let lldty = T_fn(~[T_ptr(type_of(ccx, ty::mk_nil(tcx))),
T_ptr(type_of(ccx, class_ty))],
llvm::LLVMVoidType());
let lldty = unsafe {
T_fn(~[
T_ptr(type_of(ccx, ty::mk_nil(tcx))),
T_ptr(type_of(ccx, class_ty))
],
llvm::LLVMVoidType())
};
let s = get_dtor_symbol(ccx, /*bad*/copy *pt, dt.node.id, None);
/* Make the declaration for the dtor */
@@ -2357,10 +2440,14 @@ fn trans_constant(ccx: @crate_ctxt, it: @ast::item) {
// XXX: Bad copy.
note_unique_llvm_symbol(ccx, copy s);
let discrim_gvar = str::as_c_str(s, |buf| {
llvm::LLVMAddGlobal(ccx.llmod, ccx.int_type, buf)
unsafe {
llvm::LLVMAddGlobal(ccx.llmod, ccx.int_type, buf)
}
});
llvm::LLVMSetInitializer(discrim_gvar, C_int(ccx, disr_val));
llvm::LLVMSetGlobalConstant(discrim_gvar, True);
unsafe {
llvm::LLVMSetInitializer(discrim_gvar, C_int(ccx, disr_val));
llvm::LLVMSetGlobalConstant(discrim_gvar, True);
}
ccx.discrims.insert(
local_def(variant.node.id), discrim_gvar);
ccx.discrim_symbols.insert(variant.node.id, s);
@@ -2386,7 +2473,9 @@ fn vp2i(cx: block, v: ValueRef) -> ValueRef {
}
fn p2i(ccx: @crate_ctxt, v: ValueRef) -> ValueRef {
return llvm::LLVMConstPtrToInt(v, ccx.int_type);
unsafe {
return llvm::LLVMConstPtrToInt(v, ccx.int_type);
}
}
fn declare_intrinsics(llmod: ModuleRef) -> HashMap<~str, ValueRef> {
@@ -2602,20 +2691,28 @@ fn decl_gc_metadata(ccx: @crate_ctxt, llmod_id: ~str) {
let gc_metadata_name = ~"_gc_module_metadata_" + llmod_id;
let gc_metadata = do str::as_c_str(gc_metadata_name) |buf| {
llvm::LLVMAddGlobal(ccx.llmod, T_i32(), buf)
unsafe {
llvm::LLVMAddGlobal(ccx.llmod, T_i32(), buf)
}
};
llvm::LLVMSetGlobalConstant(gc_metadata, True);
lib::llvm::SetLinkage(gc_metadata, lib::llvm::ExternalLinkage);
ccx.module_data.insert(~"_gc_module_metadata", gc_metadata);
unsafe {
llvm::LLVMSetGlobalConstant(gc_metadata, True);
lib::llvm::SetLinkage(gc_metadata, lib::llvm::ExternalLinkage);
ccx.module_data.insert(~"_gc_module_metadata", gc_metadata);
}
}
fn create_module_map(ccx: @crate_ctxt) -> ValueRef {
let elttype = T_struct(~[ccx.int_type, ccx.int_type]);
let maptype = T_array(elttype, ccx.module_data.size() + 1u);
let map = str::as_c_str(~"_rust_mod_map", |buf| {
llvm::LLVMAddGlobal(ccx.llmod, maptype, buf)
unsafe {
llvm::LLVMAddGlobal(ccx.llmod, maptype, buf)
}
});
lib::llvm::SetLinkage(map, lib::llvm::InternalLinkage);
unsafe {
lib::llvm::SetLinkage(map, lib::llvm::InternalLinkage);
}
let mut elts: ~[ValueRef] = ~[];
for ccx.module_data.each |key, val| {
let elt = C_struct(~[p2i(ccx, C_cstr(ccx, key)),
@@ -2624,7 +2721,9 @@ fn create_module_map(ccx: @crate_ctxt) -> ValueRef {
}
let term = C_struct(~[C_int(ccx, 0), C_int(ccx, 0)]);
elts.push(term);
llvm::LLVMSetInitializer(map, C_array(elttype, elts));
unsafe {
llvm::LLVMSetInitializer(map, C_array(elttype, elts));
}
return map;
}
@@ -2643,7 +2742,9 @@ fn decl_crate_map(sess: session::Session, mapmeta: link_meta,
let arrtype = T_array(int_type, n_subcrates as uint);
let maptype = T_struct(~[T_i32(), T_ptr(T_i8()), int_type, arrtype]);
let map = str::as_c_str(sym_name, |buf| {
llvm::LLVMAddGlobal(llmod, maptype, buf)
unsafe {
llvm::LLVMAddGlobal(llmod, maptype, buf)
}
});
lib::llvm::SetLinkage(map, lib::llvm::ExternalLinkage);
return map;
@@ -2659,7 +2760,9 @@ fn fill_crate_map(ccx: @crate_ctxt, map: ValueRef) {
~"_" + cstore::get_crate_vers(cstore, i) +
~"_" + cstore::get_crate_hash(cstore, i);
let cr = str::as_c_str(nm, |buf| {
llvm::LLVMAddGlobal(ccx.llmod, ccx.int_type, buf)
unsafe {
llvm::LLVMAddGlobal(ccx.llmod, ccx.int_type, buf)
}
});
subcrates.push(p2i(ccx, cr));
i += 1;
@@ -2678,12 +2781,14 @@ fn fill_crate_map(ccx: @crate_ctxt, map: ValueRef) {
annihilate_fn_type);
}
llvm::LLVMSetInitializer(map, C_struct(
~[C_i32(1),
lib::llvm::llvm::LLVMConstPointerCast(llannihilatefn,
T_ptr(T_i8())),
p2i(ccx, create_module_map(ccx)),
C_array(ccx.int_type, subcrates)]));
unsafe {
llvm::LLVMSetInitializer(map, C_struct(
~[C_i32(1),
lib::llvm::llvm::LLVMConstPointerCast(llannihilatefn,
T_ptr(T_i8())),
p2i(ccx, create_module_map(ccx)),
C_array(ccx.int_type, subcrates)]));
}
}
fn crate_ctxt_to_encode_parms(cx: @crate_ctxt) -> encoder::encode_parms {
@@ -2710,21 +2815,25 @@ fn write_metadata(cx: @crate_ctxt, crate: @ast::crate) {
let llmeta = C_bytes(encoder::encode_metadata(encode_parms, crate));
let llconst = C_struct(~[llmeta]);
let mut llglobal = str::as_c_str(~"rust_metadata", |buf| {
llvm::LLVMAddGlobal(cx.llmod, val_ty(llconst), buf)
unsafe {
llvm::LLVMAddGlobal(cx.llmod, val_ty(llconst), buf)
}
});
llvm::LLVMSetInitializer(llglobal, llconst);
str::as_c_str(cx.sess.targ_cfg.target_strs.meta_sect_name, |buf| {
llvm::LLVMSetSection(llglobal, buf)
});
lib::llvm::SetLinkage(llglobal, lib::llvm::InternalLinkage);
unsafe {
llvm::LLVMSetInitializer(llglobal, llconst);
str::as_c_str(cx.sess.targ_cfg.target_strs.meta_sect_name, |buf| {
llvm::LLVMSetSection(llglobal, buf)
});
lib::llvm::SetLinkage(llglobal, lib::llvm::InternalLinkage);
let t_ptr_i8 = T_ptr(T_i8());
llglobal = llvm::LLVMConstBitCast(llglobal, t_ptr_i8);
let llvm_used = str::as_c_str(~"llvm.used", |buf| {
llvm::LLVMAddGlobal(cx.llmod, T_array(t_ptr_i8, 1u), buf)
});
lib::llvm::SetLinkage(llvm_used, lib::llvm::AppendingLinkage);
llvm::LLVMSetInitializer(llvm_used, C_array(t_ptr_i8, ~[llglobal]));
let t_ptr_i8 = T_ptr(T_i8());
llglobal = llvm::LLVMConstBitCast(llglobal, t_ptr_i8);
let llvm_used = str::as_c_str(~"llvm.used", |buf| {
llvm::LLVMAddGlobal(cx.llmod, T_array(t_ptr_i8, 1u), buf)
});
lib::llvm::SetLinkage(llvm_used, lib::llvm::AppendingLinkage);
llvm::LLVMSetInitializer(llvm_used, C_array(t_ptr_i8, ~[llglobal]));
}
}
// Writes the current ABI version into the crate.
@@ -2757,140 +2866,142 @@ fn trans_crate(sess: session::Session,
// 1. http://llvm.org/bugs/show_bug.cgi?id=11479
let llmod_id = link_meta.name + ~".rc";
let llmod = str::as_c_str(llmod_id, |buf| {
llvm::LLVMModuleCreateWithNameInContext
(buf, llvm::LLVMGetGlobalContext())
});
let data_layout = /*bad*/copy sess.targ_cfg.target_strs.data_layout;
let targ_triple = /*bad*/copy sess.targ_cfg.target_strs.target_triple;
let _: () =
str::as_c_str(data_layout,
|buf| llvm::LLVMSetDataLayout(llmod, buf));
let _: () =
str::as_c_str(targ_triple,
|buf| llvm::LLVMSetTarget(llmod, buf));
let targ_cfg = sess.targ_cfg;
let td = mk_target_data(
/*bad*/copy sess.targ_cfg.target_strs.data_layout);
let tn = mk_type_names();
let intrinsics = declare_intrinsics(llmod);
if sess.opts.extra_debuginfo {
declare_dbg_intrinsics(llmod, intrinsics);
}
let int_type = T_int(targ_cfg);
let float_type = T_float(targ_cfg);
let task_type = T_task(targ_cfg);
let taskptr_type = T_ptr(task_type);
lib::llvm::associate_type(tn, ~"taskptr", taskptr_type);
let tydesc_type = T_tydesc(targ_cfg);
lib::llvm::associate_type(tn, ~"tydesc", tydesc_type);
let crate_map = decl_crate_map(sess, link_meta, llmod);
let dbg_cx = if sess.opts.debuginfo {
Some(debuginfo::mk_ctxt(copy llmod_id, sess.parse_sess.interner))
} else {
None
};
let ccx = @crate_ctxt {
sess: sess,
llmod: llmod,
td: td,
tn: tn,
externs: HashMap(),
intrinsics: intrinsics,
item_vals: HashMap(),
exp_map2: emap2,
reachable: reachable,
item_symbols: HashMap(),
mut main_fn: None::<ValueRef>,
link_meta: copy link_meta, // XXX: Bad copy.
enum_sizes: ty::new_ty_hash(),
discrims: HashMap(),
discrim_symbols: HashMap(),
tydescs: ty::new_ty_hash(),
mut finished_tydescs: false,
external: HashMap(),
monomorphized: HashMap(),
monomorphizing: HashMap(),
type_use_cache: HashMap(),
vtables: map::HashMap(),
const_cstr_cache: HashMap(),
const_globals: HashMap(),
const_values: HashMap(),
module_data: HashMap(),
lltypes: ty::new_ty_hash(),
names: new_namegen(sess.parse_sess.interner),
next_addrspace: new_addrspace_gen(),
symbol_hasher: symbol_hasher,
type_hashcodes: ty::new_ty_hash(),
type_short_names: ty::new_ty_hash(),
all_llvm_symbols: HashMap(),
tcx: tcx,
maps: maps,
stats:
{mut n_static_tydescs: 0u,
mut n_glues_created: 0u,
mut n_null_glues: 0u,
mut n_real_glues: 0u,
mut n_fns: 0u,
mut n_monos: 0u,
mut n_inlines: 0u,
mut n_closures: 0u,
llvm_insn_ctxt: @mut ~[],
llvm_insns: HashMap(),
fn_times: @mut ~[]},
upcalls: upcall::declare_upcalls(targ_cfg, llmod),
tydesc_type: tydesc_type,
int_type: int_type,
float_type: float_type,
task_type: task_type,
opaque_vec_type: T_opaque_vec(targ_cfg),
builder: BuilderRef_res(llvm::LLVMCreateBuilder()),
shape_cx: mk_ctxt(llmod),
crate_map: crate_map,
mut uses_gc: false,
dbg_cx: dbg_cx,
mut do_not_commit_warning_issued: false
};
{
let _icx = ccx.insn_ctxt("data");
trans_constants(ccx, crate);
}
{
let _icx = ccx.insn_ctxt("text");
trans_mod(ccx, crate.node.module);
}
decl_gc_metadata(ccx, llmod_id);
fill_crate_map(ccx, crate_map);
glue::emit_tydescs(ccx);
write_abi_version(ccx);
// Translate the metadata.
write_metadata(ccx, crate);
if ccx.sess.trans_stats() {
io::println(~"--- trans stats ---");
io::println(fmt!("n_static_tydescs: %u",
ccx.stats.n_static_tydescs));
io::println(fmt!("n_glues_created: %u",
ccx.stats.n_glues_created));
io::println(fmt!("n_null_glues: %u", ccx.stats.n_null_glues));
io::println(fmt!("n_real_glues: %u", ccx.stats.n_real_glues));
io::println(fmt!("n_fns: %u", ccx.stats.n_fns));
io::println(fmt!("n_monos: %u", ccx.stats.n_monos));
io::println(fmt!("n_inlines: %u", ccx.stats.n_inlines));
io::println(fmt!("n_closures: %u", ccx.stats.n_closures));
}
if ccx.sess.count_llvm_insns() {
for ccx.stats.llvm_insns.each |k, v| {
io::println(fmt!("%-7u %s", v, k));
unsafe {
let llmod = str::as_c_str(llmod_id, |buf| {
llvm::LLVMModuleCreateWithNameInContext
(buf, llvm::LLVMGetGlobalContext())
});
let data_layout = /*bad*/copy sess.targ_cfg.target_strs.data_layout;
let targ_triple = /*bad*/copy sess.targ_cfg.target_strs.target_triple;
let _: () =
str::as_c_str(data_layout,
|buf| llvm::LLVMSetDataLayout(llmod, buf));
let _: () =
str::as_c_str(targ_triple,
|buf| llvm::LLVMSetTarget(llmod, buf));
let targ_cfg = sess.targ_cfg;
let td = mk_target_data(
/*bad*/copy sess.targ_cfg.target_strs.data_layout);
let tn = mk_type_names();
let intrinsics = declare_intrinsics(llmod);
if sess.opts.extra_debuginfo {
declare_dbg_intrinsics(llmod, intrinsics);
}
let int_type = T_int(targ_cfg);
let float_type = T_float(targ_cfg);
let task_type = T_task(targ_cfg);
let taskptr_type = T_ptr(task_type);
lib::llvm::associate_type(tn, ~"taskptr", taskptr_type);
let tydesc_type = T_tydesc(targ_cfg);
lib::llvm::associate_type(tn, ~"tydesc", tydesc_type);
let crate_map = decl_crate_map(sess, link_meta, llmod);
let dbg_cx = if sess.opts.debuginfo {
Some(debuginfo::mk_ctxt(copy llmod_id, sess.parse_sess.interner))
} else {
None
};
let ccx = @crate_ctxt {
sess: sess,
llmod: llmod,
td: td,
tn: tn,
externs: HashMap(),
intrinsics: intrinsics,
item_vals: HashMap(),
exp_map2: emap2,
reachable: reachable,
item_symbols: HashMap(),
mut main_fn: None::<ValueRef>,
link_meta: copy link_meta, // XXX: Bad copy.
enum_sizes: ty::new_ty_hash(),
discrims: HashMap(),
discrim_symbols: HashMap(),
tydescs: ty::new_ty_hash(),
mut finished_tydescs: false,
external: HashMap(),
monomorphized: HashMap(),
monomorphizing: HashMap(),
type_use_cache: HashMap(),
vtables: map::HashMap(),
const_cstr_cache: HashMap(),
const_globals: HashMap(),
const_values: HashMap(),
module_data: HashMap(),
lltypes: ty::new_ty_hash(),
names: new_namegen(sess.parse_sess.interner),
next_addrspace: new_addrspace_gen(),
symbol_hasher: symbol_hasher,
type_hashcodes: ty::new_ty_hash(),
type_short_names: ty::new_ty_hash(),
all_llvm_symbols: HashMap(),
tcx: tcx,
maps: maps,
stats:
{mut n_static_tydescs: 0u,
mut n_glues_created: 0u,
mut n_null_glues: 0u,
mut n_real_glues: 0u,
mut n_fns: 0u,
mut n_monos: 0u,
mut n_inlines: 0u,
mut n_closures: 0u,
llvm_insn_ctxt: @mut ~[],
llvm_insns: HashMap(),
fn_times: @mut ~[]},
upcalls: upcall::declare_upcalls(targ_cfg, llmod),
tydesc_type: tydesc_type,
int_type: int_type,
float_type: float_type,
task_type: task_type,
opaque_vec_type: T_opaque_vec(targ_cfg),
builder: BuilderRef_res(unsafe { llvm::LLVMCreateBuilder() }),
shape_cx: mk_ctxt(llmod),
crate_map: crate_map,
mut uses_gc: false,
dbg_cx: dbg_cx,
mut do_not_commit_warning_issued: false
};
{
let _icx = ccx.insn_ctxt("data");
trans_constants(ccx, crate);
}
{
let _icx = ccx.insn_ctxt("text");
trans_mod(ccx, crate.node.module);
}
decl_gc_metadata(ccx, llmod_id);
fill_crate_map(ccx, crate_map);
glue::emit_tydescs(ccx);
write_abi_version(ccx);
// Translate the metadata.
write_metadata(ccx, crate);
if ccx.sess.trans_stats() {
io::println(~"--- trans stats ---");
io::println(fmt!("n_static_tydescs: %u",
ccx.stats.n_static_tydescs));
io::println(fmt!("n_glues_created: %u",
ccx.stats.n_glues_created));
io::println(fmt!("n_null_glues: %u", ccx.stats.n_null_glues));
io::println(fmt!("n_real_glues: %u", ccx.stats.n_real_glues));
io::println(fmt!("n_fns: %u", ccx.stats.n_fns));
io::println(fmt!("n_monos: %u", ccx.stats.n_monos));
io::println(fmt!("n_inlines: %u", ccx.stats.n_inlines));
io::println(fmt!("n_closures: %u", ccx.stats.n_closures));
}
if ccx.sess.count_llvm_insns() {
for ccx.stats.llvm_insns.each |k, v| {
io::println(fmt!("%-7u %s", v, k));
}
}
return (llmod, link_meta);
}
return (llmod, link_meta);
}
//
// Local Variables:
+524 -340
View File
@@ -25,9 +25,11 @@
use syntax::codemap;
fn B(cx: block) -> BuilderRef {
let b = cx.fcx.ccx.builder.B;
llvm::LLVMPositionBuilderAtEnd(b, cx.llbb);
return b;
unsafe {
let b = cx.fcx.ccx.builder.B;
llvm::LLVMPositionBuilderAtEnd(b, cx.llbb);
return b;
}
}
fn count_insn(cx: block, category: &str) {
@@ -82,19 +84,23 @@ fn count_insn(cx: block, category: &str) {
// further instructions to the block should simply be ignored.
fn RetVoid(cx: block) {
if cx.unreachable { return; }
assert (!cx.terminated);
cx.terminated = true;
count_insn(cx, "retvoid");
llvm::LLVMBuildRetVoid(B(cx));
unsafe {
if cx.unreachable { return; }
assert (!cx.terminated);
cx.terminated = true;
count_insn(cx, "retvoid");
llvm::LLVMBuildRetVoid(B(cx));
}
}
fn Ret(cx: block, V: ValueRef) {
if cx.unreachable { return; }
assert (!cx.terminated);
cx.terminated = true;
count_insn(cx, "ret");
llvm::LLVMBuildRet(B(cx), V);
unsafe {
if cx.unreachable { return; }
assert (!cx.terminated);
cx.terminated = true;
count_insn(cx, "ret");
llvm::LLVMBuildRet(B(cx), V);
}
}
fn AggregateRet(cx: block, RetVals: ~[ValueRef]) {
@@ -108,41 +114,51 @@ fn AggregateRet(cx: block, RetVals: ~[ValueRef]) {
}
fn Br(cx: block, Dest: BasicBlockRef) {
if cx.unreachable { return; }
assert (!cx.terminated);
cx.terminated = true;
count_insn(cx, "br");
llvm::LLVMBuildBr(B(cx), Dest);
unsafe {
if cx.unreachable { return; }
assert (!cx.terminated);
cx.terminated = true;
count_insn(cx, "br");
llvm::LLVMBuildBr(B(cx), Dest);
}
}
fn CondBr(cx: block, If: ValueRef, Then: BasicBlockRef,
Else: BasicBlockRef) {
if cx.unreachable { return; }
assert (!cx.terminated);
cx.terminated = true;
count_insn(cx, "condbr");
llvm::LLVMBuildCondBr(B(cx), If, Then, Else);
unsafe {
if cx.unreachable { return; }
assert (!cx.terminated);
cx.terminated = true;
count_insn(cx, "condbr");
llvm::LLVMBuildCondBr(B(cx), If, Then, Else);
}
}
fn Switch(cx: block, V: ValueRef, Else: BasicBlockRef, NumCases: uint)
-> ValueRef {
if cx.unreachable { return _Undef(V); }
assert !cx.terminated;
cx.terminated = true;
return llvm::LLVMBuildSwitch(B(cx), V, Else, NumCases as c_uint);
unsafe {
if cx.unreachable { return _Undef(V); }
assert !cx.terminated;
cx.terminated = true;
return llvm::LLVMBuildSwitch(B(cx), V, Else, NumCases as c_uint);
}
}
fn AddCase(S: ValueRef, OnVal: ValueRef, Dest: BasicBlockRef) {
if llvm::LLVMIsUndef(S) == lib::llvm::True { return; }
llvm::LLVMAddCase(S, OnVal, Dest);
unsafe {
if llvm::LLVMIsUndef(S) == lib::llvm::True { return; }
llvm::LLVMAddCase(S, OnVal, Dest);
}
}
fn IndirectBr(cx: block, Addr: ValueRef, NumDests: uint) {
if cx.unreachable { return; }
assert (!cx.terminated);
cx.terminated = true;
count_insn(cx, "indirectbr");
llvm::LLVMBuildIndirectBr(B(cx), Addr, NumDests as c_uint);
unsafe {
if cx.unreachable { return; }
assert (!cx.terminated);
cx.terminated = true;
count_insn(cx, "indirectbr");
llvm::LLVMBuildIndirectBr(B(cx), Addr, NumDests as c_uint);
}
}
// This is a really awful way to get a zero-length c-string, but better (and a
@@ -184,263 +200,342 @@ fn FastInvoke(cx: block, Fn: ValueRef, Args: ~[ValueRef],
}
fn Unreachable(cx: block) {
if cx.unreachable { return; }
cx.unreachable = true;
if !cx.terminated {
count_insn(cx, "unreachable");
llvm::LLVMBuildUnreachable(B(cx));
unsafe {
if cx.unreachable { return; }
cx.unreachable = true;
if !cx.terminated {
count_insn(cx, "unreachable");
llvm::LLVMBuildUnreachable(B(cx));
}
}
}
fn _Undef(val: ValueRef) -> ValueRef {
return llvm::LLVMGetUndef(val_ty(val));
unsafe {
return llvm::LLVMGetUndef(val_ty(val));
}
}
/* Arithmetic */
fn Add(cx: block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
if cx.unreachable { return _Undef(LHS); }
count_insn(cx, "add");
return llvm::LLVMBuildAdd(B(cx), LHS, RHS, noname());
unsafe {
if cx.unreachable { return _Undef(LHS); }
count_insn(cx, "add");
return llvm::LLVMBuildAdd(B(cx), LHS, RHS, noname());
}
}
fn NSWAdd(cx: block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
if cx.unreachable { return _Undef(LHS); }
count_insn(cx, "nswadd");
return llvm::LLVMBuildNSWAdd(B(cx), LHS, RHS, noname());
unsafe {
if cx.unreachable { return _Undef(LHS); }
count_insn(cx, "nswadd");
return llvm::LLVMBuildNSWAdd(B(cx), LHS, RHS, noname());
}
}
fn NUWAdd(cx: block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
if cx.unreachable { return _Undef(LHS); }
count_insn(cx, "nuwadd");
return llvm::LLVMBuildNUWAdd(B(cx), LHS, RHS, noname());
unsafe {
if cx.unreachable { return _Undef(LHS); }
count_insn(cx, "nuwadd");
return llvm::LLVMBuildNUWAdd(B(cx), LHS, RHS, noname());
}
}
fn FAdd(cx: block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
if cx.unreachable { return _Undef(LHS); }
count_insn(cx, "fadd");
return llvm::LLVMBuildFAdd(B(cx), LHS, RHS, noname());
unsafe {
if cx.unreachable { return _Undef(LHS); }
count_insn(cx, "fadd");
return llvm::LLVMBuildFAdd(B(cx), LHS, RHS, noname());
}
}
fn Sub(cx: block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
if cx.unreachable { return _Undef(LHS); }
count_insn(cx, "sub");
return llvm::LLVMBuildSub(B(cx), LHS, RHS, noname());
unsafe {
if cx.unreachable { return _Undef(LHS); }
count_insn(cx, "sub");
return llvm::LLVMBuildSub(B(cx), LHS, RHS, noname());
}
}
fn NSWSub(cx: block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
if cx.unreachable { return _Undef(LHS); }
count_insn(cx, "nwsub");
return llvm::LLVMBuildNSWSub(B(cx), LHS, RHS, noname());
unsafe {
if cx.unreachable { return _Undef(LHS); }
count_insn(cx, "nwsub");
return llvm::LLVMBuildNSWSub(B(cx), LHS, RHS, noname());
}
}
fn NUWSub(cx: block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
if cx.unreachable { return _Undef(LHS); }
count_insn(cx, "nuwsub");
return llvm::LLVMBuildNUWSub(B(cx), LHS, RHS, noname());
unsafe {
if cx.unreachable { return _Undef(LHS); }
count_insn(cx, "nuwsub");
return llvm::LLVMBuildNUWSub(B(cx), LHS, RHS, noname());
}
}
fn FSub(cx: block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
if cx.unreachable { return _Undef(LHS); }
count_insn(cx, "sub");
return llvm::LLVMBuildFSub(B(cx), LHS, RHS, noname());
unsafe {
if cx.unreachable { return _Undef(LHS); }
count_insn(cx, "sub");
return llvm::LLVMBuildFSub(B(cx), LHS, RHS, noname());
}
}
fn Mul(cx: block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
if cx.unreachable { return _Undef(LHS); }
count_insn(cx, "mul");
return llvm::LLVMBuildMul(B(cx), LHS, RHS, noname());
unsafe {
if cx.unreachable { return _Undef(LHS); }
count_insn(cx, "mul");
return llvm::LLVMBuildMul(B(cx), LHS, RHS, noname());
}
}
fn NSWMul(cx: block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
if cx.unreachable { return _Undef(LHS); }
count_insn(cx, "nswmul");
return llvm::LLVMBuildNSWMul(B(cx), LHS, RHS, noname());
unsafe {
if cx.unreachable { return _Undef(LHS); }
count_insn(cx, "nswmul");
return llvm::LLVMBuildNSWMul(B(cx), LHS, RHS, noname());
}
}
fn NUWMul(cx: block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
if cx.unreachable { return _Undef(LHS); }
count_insn(cx, "nuwmul");
return llvm::LLVMBuildNUWMul(B(cx), LHS, RHS, noname());
unsafe {
if cx.unreachable { return _Undef(LHS); }
count_insn(cx, "nuwmul");
return llvm::LLVMBuildNUWMul(B(cx), LHS, RHS, noname());
}
}
fn FMul(cx: block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
if cx.unreachable { return _Undef(LHS); }
count_insn(cx, "fmul");
return llvm::LLVMBuildFMul(B(cx), LHS, RHS, noname());
unsafe {
if cx.unreachable { return _Undef(LHS); }
count_insn(cx, "fmul");
return llvm::LLVMBuildFMul(B(cx), LHS, RHS, noname());
}
}
fn UDiv(cx: block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
if cx.unreachable { return _Undef(LHS); }
count_insn(cx, "udiv");
return llvm::LLVMBuildUDiv(B(cx), LHS, RHS, noname());
unsafe {
if cx.unreachable { return _Undef(LHS); }
count_insn(cx, "udiv");
return llvm::LLVMBuildUDiv(B(cx), LHS, RHS, noname());
}
}
fn SDiv(cx: block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
if cx.unreachable { return _Undef(LHS); }
count_insn(cx, "sdiv");
return llvm::LLVMBuildSDiv(B(cx), LHS, RHS, noname());
unsafe {
if cx.unreachable { return _Undef(LHS); }
count_insn(cx, "sdiv");
return llvm::LLVMBuildSDiv(B(cx), LHS, RHS, noname());
}
}
fn ExactSDiv(cx: block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
if cx.unreachable { return _Undef(LHS); }
count_insn(cx, "extractsdiv");
return llvm::LLVMBuildExactSDiv(B(cx), LHS, RHS, noname());
unsafe {
if cx.unreachable { return _Undef(LHS); }
count_insn(cx, "extractsdiv");
return llvm::LLVMBuildExactSDiv(B(cx), LHS, RHS, noname());
}
}
fn FDiv(cx: block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
if cx.unreachable { return _Undef(LHS); }
count_insn(cx, "fdiv");
return llvm::LLVMBuildFDiv(B(cx), LHS, RHS, noname());
unsafe {
if cx.unreachable { return _Undef(LHS); }
count_insn(cx, "fdiv");
return llvm::LLVMBuildFDiv(B(cx), LHS, RHS, noname());
}
}
fn URem(cx: block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
if cx.unreachable { return _Undef(LHS); }
count_insn(cx, "urem");
return llvm::LLVMBuildURem(B(cx), LHS, RHS, noname());
unsafe {
if cx.unreachable { return _Undef(LHS); }
count_insn(cx, "urem");
return llvm::LLVMBuildURem(B(cx), LHS, RHS, noname());
}
}
fn SRem(cx: block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
if cx.unreachable { return _Undef(LHS); }
count_insn(cx, "srem");
return llvm::LLVMBuildSRem(B(cx), LHS, RHS, noname());
unsafe {
if cx.unreachable { return _Undef(LHS); }
count_insn(cx, "srem");
return llvm::LLVMBuildSRem(B(cx), LHS, RHS, noname());
}
}
fn FRem(cx: block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
if cx.unreachable { return _Undef(LHS); }
count_insn(cx, "frem");
return llvm::LLVMBuildFRem(B(cx), LHS, RHS, noname());
unsafe {
if cx.unreachable { return _Undef(LHS); }
count_insn(cx, "frem");
return llvm::LLVMBuildFRem(B(cx), LHS, RHS, noname());
}
}
fn Shl(cx: block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
if cx.unreachable { return _Undef(LHS); }
count_insn(cx, "shl");
return llvm::LLVMBuildShl(B(cx), LHS, RHS, noname());
unsafe {
if cx.unreachable { return _Undef(LHS); }
count_insn(cx, "shl");
return llvm::LLVMBuildShl(B(cx), LHS, RHS, noname());
}
}
fn LShr(cx: block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
if cx.unreachable { return _Undef(LHS); }
count_insn(cx, "lshr");
return llvm::LLVMBuildLShr(B(cx), LHS, RHS, noname());
unsafe {
if cx.unreachable { return _Undef(LHS); }
count_insn(cx, "lshr");
return llvm::LLVMBuildLShr(B(cx), LHS, RHS, noname());
}
}
fn AShr(cx: block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
if cx.unreachable { return _Undef(LHS); }
count_insn(cx, "ashr");
return llvm::LLVMBuildAShr(B(cx), LHS, RHS, noname());
unsafe {
if cx.unreachable { return _Undef(LHS); }
count_insn(cx, "ashr");
return llvm::LLVMBuildAShr(B(cx), LHS, RHS, noname());
}
}
fn And(cx: block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
if cx.unreachable { return _Undef(LHS); }
count_insn(cx, "and");
return llvm::LLVMBuildAnd(B(cx), LHS, RHS, noname());
unsafe {
if cx.unreachable { return _Undef(LHS); }
count_insn(cx, "and");
return llvm::LLVMBuildAnd(B(cx), LHS, RHS, noname());
}
}
fn Or(cx: block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
if cx.unreachable { return _Undef(LHS); }
count_insn(cx, "or");
return llvm::LLVMBuildOr(B(cx), LHS, RHS, noname());
unsafe {
if cx.unreachable { return _Undef(LHS); }
count_insn(cx, "or");
return llvm::LLVMBuildOr(B(cx), LHS, RHS, noname());
}
}
fn Xor(cx: block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
if cx.unreachable { return _Undef(LHS); }
count_insn(cx, "xor");
return llvm::LLVMBuildXor(B(cx), LHS, RHS, noname());
unsafe {
if cx.unreachable { return _Undef(LHS); }
count_insn(cx, "xor");
return llvm::LLVMBuildXor(B(cx), LHS, RHS, noname());
}
}
fn BinOp(cx: block, Op: Opcode, LHS: ValueRef, RHS: ValueRef) ->
ValueRef {
if cx.unreachable { return _Undef(LHS); }
count_insn(cx, "binop");
return llvm::LLVMBuildBinOp(B(cx), Op, LHS, RHS, noname());
fn BinOp(cx: block, Op: Opcode, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
unsafe {
if cx.unreachable { return _Undef(LHS); }
count_insn(cx, "binop");
return llvm::LLVMBuildBinOp(B(cx), Op, LHS, RHS, noname());
}
}
fn Neg(cx: block, V: ValueRef) -> ValueRef {
if cx.unreachable { return _Undef(V); }
count_insn(cx, "neg");
return llvm::LLVMBuildNeg(B(cx), V, noname());
unsafe {
if cx.unreachable { return _Undef(V); }
count_insn(cx, "neg");
return llvm::LLVMBuildNeg(B(cx), V, noname());
}
}
fn NSWNeg(cx: block, V: ValueRef) -> ValueRef {
if cx.unreachable { return _Undef(V); }
count_insn(cx, "nswneg");
return llvm::LLVMBuildNSWNeg(B(cx), V, noname());
unsafe {
if cx.unreachable { return _Undef(V); }
count_insn(cx, "nswneg");
return llvm::LLVMBuildNSWNeg(B(cx), V, noname());
}
}
fn NUWNeg(cx: block, V: ValueRef) -> ValueRef {
if cx.unreachable { return _Undef(V); }
count_insn(cx, "nuwneg");
return llvm::LLVMBuildNUWNeg(B(cx), V, noname());
unsafe {
if cx.unreachable { return _Undef(V); }
count_insn(cx, "nuwneg");
return llvm::LLVMBuildNUWNeg(B(cx), V, noname());
}
}
fn FNeg(cx: block, V: ValueRef) -> ValueRef {
if cx.unreachable { return _Undef(V); }
count_insn(cx, "fneg");
return llvm::LLVMBuildFNeg(B(cx), V, noname());
unsafe {
if cx.unreachable { return _Undef(V); }
count_insn(cx, "fneg");
return llvm::LLVMBuildFNeg(B(cx), V, noname());
}
}
fn Not(cx: block, V: ValueRef) -> ValueRef {
if cx.unreachable { return _Undef(V); }
count_insn(cx, "not");
return llvm::LLVMBuildNot(B(cx), V, noname());
unsafe {
if cx.unreachable { return _Undef(V); }
count_insn(cx, "not");
return llvm::LLVMBuildNot(B(cx), V, noname());
}
}
/* Memory */
fn Malloc(cx: block, Ty: TypeRef) -> ValueRef {
if cx.unreachable { return llvm::LLVMGetUndef(T_ptr(T_i8())); }
count_insn(cx, "malloc");
return llvm::LLVMBuildMalloc(B(cx), Ty, noname());
unsafe {
if cx.unreachable { return llvm::LLVMGetUndef(T_ptr(T_i8())); }
count_insn(cx, "malloc");
return llvm::LLVMBuildMalloc(B(cx), Ty, noname());
}
}
fn ArrayMalloc(cx: block, Ty: TypeRef, Val: ValueRef) -> ValueRef {
if cx.unreachable { return llvm::LLVMGetUndef(T_ptr(T_i8())); }
count_insn(cx, "arraymalloc");
return llvm::LLVMBuildArrayMalloc(B(cx), Ty, Val, noname());
unsafe {
if cx.unreachable { return llvm::LLVMGetUndef(T_ptr(T_i8())); }
count_insn(cx, "arraymalloc");
return llvm::LLVMBuildArrayMalloc(B(cx), Ty, Val, noname());
}
}
fn Alloca(cx: block, Ty: TypeRef) -> ValueRef {
if cx.unreachable { return llvm::LLVMGetUndef(T_ptr(Ty)); }
count_insn(cx, "alloca");
return llvm::LLVMBuildAlloca(B(cx), Ty, noname());
unsafe {
if cx.unreachable { return llvm::LLVMGetUndef(T_ptr(Ty)); }
count_insn(cx, "alloca");
return llvm::LLVMBuildAlloca(B(cx), Ty, noname());
}
}
fn ArrayAlloca(cx: block, Ty: TypeRef, Val: ValueRef) -> ValueRef {
if cx.unreachable { return llvm::LLVMGetUndef(T_ptr(Ty)); }
count_insn(cx, "arrayalloca");
return llvm::LLVMBuildArrayAlloca(B(cx), Ty, Val, noname());
unsafe {
if cx.unreachable { return llvm::LLVMGetUndef(T_ptr(Ty)); }
count_insn(cx, "arrayalloca");
return llvm::LLVMBuildArrayAlloca(B(cx), Ty, Val, noname());
}
}
fn Free(cx: block, PointerVal: ValueRef) {
if cx.unreachable { return; }
count_insn(cx, "free");
llvm::LLVMBuildFree(B(cx), PointerVal);
unsafe {
if cx.unreachable { return; }
count_insn(cx, "free");
llvm::LLVMBuildFree(B(cx), PointerVal);
}
}
fn Load(cx: block, PointerVal: ValueRef) -> ValueRef {
let ccx = cx.fcx.ccx;
if cx.unreachable {
let ty = val_ty(PointerVal);
let eltty = if llvm::LLVMGetTypeKind(ty) == lib::llvm::Array {
llvm::LLVMGetElementType(ty) } else { ccx.int_type };
return llvm::LLVMGetUndef(eltty);
unsafe {
let ccx = cx.fcx.ccx;
if cx.unreachable {
let ty = val_ty(PointerVal);
let eltty = if llvm::LLVMGetTypeKind(ty) == lib::llvm::Array {
llvm::LLVMGetElementType(ty) } else { ccx.int_type };
return llvm::LLVMGetUndef(eltty);
}
count_insn(cx, "load");
return llvm::LLVMBuildLoad(B(cx), PointerVal, noname());
}
count_insn(cx, "load");
return llvm::LLVMBuildLoad(B(cx), PointerVal, noname());
}
fn Store(cx: block, Val: ValueRef, Ptr: ValueRef) {
if cx.unreachable { return; }
debug!("Store %s -> %s",
val_str(cx.ccx().tn, Val),
val_str(cx.ccx().tn, Ptr));
count_insn(cx, "store");
llvm::LLVMBuildStore(B(cx), Val, Ptr);
unsafe {
if cx.unreachable { return; }
debug!("Store %s -> %s",
val_str(cx.ccx().tn, Val),
val_str(cx.ccx().tn, Ptr));
count_insn(cx, "store");
llvm::LLVMBuildStore(B(cx), Val, Ptr);
}
}
fn GEP(cx: block, Pointer: ValueRef, Indices: ~[ValueRef]) -> ValueRef {
if cx.unreachable { return llvm::LLVMGetUndef(T_ptr(T_nil())); }
unsafe {
count_insn(cx, "gep");
return llvm::LLVMBuildGEP(B(cx), Pointer, vec::raw::to_ptr(Indices),
Indices.len() as c_uint, noname());
if cx.unreachable { return llvm::LLVMGetUndef(T_ptr(T_nil())); }
count_insn(cx, "gep");
return llvm::LLVMBuildGEP(B(cx), Pointer, vec::raw::to_ptr(Indices),
Indices.len() as c_uint, noname());
}
}
@@ -456,182 +551,234 @@ fn GEPi(cx: block, base: ValueRef, ixs: &[uint]) -> ValueRef {
fn InBoundsGEP(cx: block, Pointer: ValueRef, Indices: &[ValueRef]) ->
ValueRef {
if cx.unreachable { return llvm::LLVMGetUndef(T_ptr(T_nil())); }
unsafe {
count_insn(cx, "inboundsgep");
return llvm::LLVMBuildInBoundsGEP(B(cx), Pointer,
vec::raw::to_ptr(Indices),
Indices.len() as c_uint,
noname());
if cx.unreachable { return llvm::LLVMGetUndef(T_ptr(T_nil())); }
unsafe {
count_insn(cx, "inboundsgep");
return llvm::LLVMBuildInBoundsGEP(B(cx), Pointer,
vec::raw::to_ptr(Indices),
Indices.len() as c_uint,
noname());
}
}
}
fn StructGEP(cx: block, Pointer: ValueRef, Idx: uint) -> ValueRef {
if cx.unreachable { return llvm::LLVMGetUndef(T_ptr(T_nil())); }
count_insn(cx, "structgep");
return llvm::LLVMBuildStructGEP(B(cx), Pointer, Idx as c_uint, noname());
unsafe {
if cx.unreachable { return llvm::LLVMGetUndef(T_ptr(T_nil())); }
count_insn(cx, "structgep");
return llvm::LLVMBuildStructGEP(B(cx),
Pointer,
Idx as c_uint,
noname());
}
}
fn GlobalString(cx: block, _Str: *libc::c_char) -> ValueRef {
if cx.unreachable { return llvm::LLVMGetUndef(T_ptr(T_i8())); }
count_insn(cx, "globalstring");
return llvm::LLVMBuildGlobalString(B(cx), _Str, noname());
unsafe {
if cx.unreachable { return llvm::LLVMGetUndef(T_ptr(T_i8())); }
count_insn(cx, "globalstring");
return llvm::LLVMBuildGlobalString(B(cx), _Str, noname());
}
}
fn GlobalStringPtr(cx: block, _Str: *libc::c_char) -> ValueRef {
if cx.unreachable { return llvm::LLVMGetUndef(T_ptr(T_i8())); }
count_insn(cx, "globalstringptr");
return llvm::LLVMBuildGlobalStringPtr(B(cx), _Str, noname());
unsafe {
if cx.unreachable { return llvm::LLVMGetUndef(T_ptr(T_i8())); }
count_insn(cx, "globalstringptr");
return llvm::LLVMBuildGlobalStringPtr(B(cx), _Str, noname());
}
}
/* Casts */
fn Trunc(cx: block, Val: ValueRef, DestTy: TypeRef) -> ValueRef {
if cx.unreachable { return llvm::LLVMGetUndef(DestTy); }
count_insn(cx, "trunc");
return llvm::LLVMBuildTrunc(B(cx), Val, DestTy, noname());
unsafe {
if cx.unreachable { return llvm::LLVMGetUndef(DestTy); }
count_insn(cx, "trunc");
return llvm::LLVMBuildTrunc(B(cx), Val, DestTy, noname());
}
}
fn ZExt(cx: block, Val: ValueRef, DestTy: TypeRef) -> ValueRef {
if cx.unreachable { return llvm::LLVMGetUndef(DestTy); }
count_insn(cx, "zext");
return llvm::LLVMBuildZExt(B(cx), Val, DestTy, noname());
unsafe {
if cx.unreachable { return llvm::LLVMGetUndef(DestTy); }
count_insn(cx, "zext");
return llvm::LLVMBuildZExt(B(cx), Val, DestTy, noname());
}
}
fn SExt(cx: block, Val: ValueRef, DestTy: TypeRef) -> ValueRef {
if cx.unreachable { return llvm::LLVMGetUndef(DestTy); }
count_insn(cx, "sext");
return llvm::LLVMBuildSExt(B(cx), Val, DestTy, noname());
unsafe {
if cx.unreachable { return llvm::LLVMGetUndef(DestTy); }
count_insn(cx, "sext");
return llvm::LLVMBuildSExt(B(cx), Val, DestTy, noname());
}
}
fn FPToUI(cx: block, Val: ValueRef, DestTy: TypeRef) -> ValueRef {
if cx.unreachable { return llvm::LLVMGetUndef(DestTy); }
count_insn(cx, "fptoui");
return llvm::LLVMBuildFPToUI(B(cx), Val, DestTy, noname());
unsafe {
if cx.unreachable { return llvm::LLVMGetUndef(DestTy); }
count_insn(cx, "fptoui");
return llvm::LLVMBuildFPToUI(B(cx), Val, DestTy, noname());
}
}
fn FPToSI(cx: block, Val: ValueRef, DestTy: TypeRef) -> ValueRef {
if cx.unreachable { return llvm::LLVMGetUndef(DestTy); }
count_insn(cx, "fptosi");
return llvm::LLVMBuildFPToSI(B(cx), Val, DestTy, noname());
unsafe {
if cx.unreachable { return llvm::LLVMGetUndef(DestTy); }
count_insn(cx, "fptosi");
return llvm::LLVMBuildFPToSI(B(cx), Val, DestTy, noname());
}
}
fn UIToFP(cx: block, Val: ValueRef, DestTy: TypeRef) -> ValueRef {
if cx.unreachable { return llvm::LLVMGetUndef(DestTy); }
count_insn(cx, "uitofp");
return llvm::LLVMBuildUIToFP(B(cx), Val, DestTy, noname());
unsafe {
if cx.unreachable { return llvm::LLVMGetUndef(DestTy); }
count_insn(cx, "uitofp");
return llvm::LLVMBuildUIToFP(B(cx), Val, DestTy, noname());
}
}
fn SIToFP(cx: block, Val: ValueRef, DestTy: TypeRef) -> ValueRef {
if cx.unreachable { return llvm::LLVMGetUndef(DestTy); }
count_insn(cx, "sitofp");
return llvm::LLVMBuildSIToFP(B(cx), Val, DestTy, noname());
unsafe {
if cx.unreachable { return llvm::LLVMGetUndef(DestTy); }
count_insn(cx, "sitofp");
return llvm::LLVMBuildSIToFP(B(cx), Val, DestTy, noname());
}
}
fn FPTrunc(cx: block, Val: ValueRef, DestTy: TypeRef) -> ValueRef {
if cx.unreachable { return llvm::LLVMGetUndef(DestTy); }
count_insn(cx, "fptrunc");
return llvm::LLVMBuildFPTrunc(B(cx), Val, DestTy, noname());
unsafe {
if cx.unreachable { return llvm::LLVMGetUndef(DestTy); }
count_insn(cx, "fptrunc");
return llvm::LLVMBuildFPTrunc(B(cx), Val, DestTy, noname());
}
}
fn FPExt(cx: block, Val: ValueRef, DestTy: TypeRef) -> ValueRef {
if cx.unreachable { return llvm::LLVMGetUndef(DestTy); }
count_insn(cx, "fpext");
return llvm::LLVMBuildFPExt(B(cx), Val, DestTy, noname());
unsafe {
if cx.unreachable { return llvm::LLVMGetUndef(DestTy); }
count_insn(cx, "fpext");
return llvm::LLVMBuildFPExt(B(cx), Val, DestTy, noname());
}
}
fn PtrToInt(cx: block, Val: ValueRef, DestTy: TypeRef) -> ValueRef {
if cx.unreachable { return llvm::LLVMGetUndef(DestTy); }
count_insn(cx, "ptrtoint");
return llvm::LLVMBuildPtrToInt(B(cx), Val, DestTy, noname());
unsafe {
if cx.unreachable { return llvm::LLVMGetUndef(DestTy); }
count_insn(cx, "ptrtoint");
return llvm::LLVMBuildPtrToInt(B(cx), Val, DestTy, noname());
}
}
fn IntToPtr(cx: block, Val: ValueRef, DestTy: TypeRef) -> ValueRef {
if cx.unreachable { return llvm::LLVMGetUndef(DestTy); }
count_insn(cx, "inttoptr");
return llvm::LLVMBuildIntToPtr(B(cx), Val, DestTy, noname());
unsafe {
if cx.unreachable { return llvm::LLVMGetUndef(DestTy); }
count_insn(cx, "inttoptr");
return llvm::LLVMBuildIntToPtr(B(cx), Val, DestTy, noname());
}
}
fn BitCast(cx: block, Val: ValueRef, DestTy: TypeRef) -> ValueRef {
if cx.unreachable { return llvm::LLVMGetUndef(DestTy); }
count_insn(cx, "bitcast");
return llvm::LLVMBuildBitCast(B(cx), Val, DestTy, noname());
unsafe {
if cx.unreachable { return llvm::LLVMGetUndef(DestTy); }
count_insn(cx, "bitcast");
return llvm::LLVMBuildBitCast(B(cx), Val, DestTy, noname());
}
}
fn ZExtOrBitCast(cx: block, Val: ValueRef, DestTy: TypeRef) ->
ValueRef {
if cx.unreachable { return llvm::LLVMGetUndef(DestTy); }
count_insn(cx, "zextorbitcast");
return llvm::LLVMBuildZExtOrBitCast(B(cx), Val, DestTy, noname());
fn ZExtOrBitCast(cx: block, Val: ValueRef, DestTy: TypeRef) -> ValueRef {
unsafe {
if cx.unreachable { return llvm::LLVMGetUndef(DestTy); }
count_insn(cx, "zextorbitcast");
return llvm::LLVMBuildZExtOrBitCast(B(cx), Val, DestTy, noname());
}
}
fn SExtOrBitCast(cx: block, Val: ValueRef, DestTy: TypeRef) ->
ValueRef {
if cx.unreachable { return llvm::LLVMGetUndef(DestTy); }
count_insn(cx, "sextorbitcast");
return llvm::LLVMBuildSExtOrBitCast(B(cx), Val, DestTy, noname());
fn SExtOrBitCast(cx: block, Val: ValueRef, DestTy: TypeRef) -> ValueRef {
unsafe {
if cx.unreachable { return llvm::LLVMGetUndef(DestTy); }
count_insn(cx, "sextorbitcast");
return llvm::LLVMBuildSExtOrBitCast(B(cx), Val, DestTy, noname());
}
}
fn TruncOrBitCast(cx: block, Val: ValueRef, DestTy: TypeRef) ->
ValueRef {
if cx.unreachable { return llvm::LLVMGetUndef(DestTy); }
count_insn(cx, "truncorbitcast");
return llvm::LLVMBuildTruncOrBitCast(B(cx), Val, DestTy, noname());
fn TruncOrBitCast(cx: block, Val: ValueRef, DestTy: TypeRef) -> ValueRef {
unsafe {
if cx.unreachable { return llvm::LLVMGetUndef(DestTy); }
count_insn(cx, "truncorbitcast");
return llvm::LLVMBuildTruncOrBitCast(B(cx), Val, DestTy, noname());
}
}
fn Cast(cx: block, Op: Opcode, Val: ValueRef, DestTy: TypeRef,
_Name: *u8) -> ValueRef {
if cx.unreachable { return llvm::LLVMGetUndef(DestTy); }
count_insn(cx, "cast");
return llvm::LLVMBuildCast(B(cx), Op, Val, DestTy, noname());
fn Cast(cx: block, Op: Opcode, Val: ValueRef, DestTy: TypeRef, _: *u8)
-> ValueRef {
unsafe {
if cx.unreachable { return llvm::LLVMGetUndef(DestTy); }
count_insn(cx, "cast");
return llvm::LLVMBuildCast(B(cx), Op, Val, DestTy, noname());
}
}
fn PointerCast(cx: block, Val: ValueRef, DestTy: TypeRef) -> ValueRef {
if cx.unreachable { return llvm::LLVMGetUndef(DestTy); }
count_insn(cx, "pointercast");
return llvm::LLVMBuildPointerCast(B(cx), Val, DestTy, noname());
unsafe {
if cx.unreachable { return llvm::LLVMGetUndef(DestTy); }
count_insn(cx, "pointercast");
return llvm::LLVMBuildPointerCast(B(cx), Val, DestTy, noname());
}
}
fn IntCast(cx: block, Val: ValueRef, DestTy: TypeRef) -> ValueRef {
if cx.unreachable { return llvm::LLVMGetUndef(DestTy); }
count_insn(cx, "intcast");
return llvm::LLVMBuildIntCast(B(cx), Val, DestTy, noname());
unsafe {
if cx.unreachable { return llvm::LLVMGetUndef(DestTy); }
count_insn(cx, "intcast");
return llvm::LLVMBuildIntCast(B(cx), Val, DestTy, noname());
}
}
fn FPCast(cx: block, Val: ValueRef, DestTy: TypeRef) -> ValueRef {
if cx.unreachable { return llvm::LLVMGetUndef(DestTy); }
count_insn(cx, "fpcast");
return llvm::LLVMBuildFPCast(B(cx), Val, DestTy, noname());
unsafe {
if cx.unreachable { return llvm::LLVMGetUndef(DestTy); }
count_insn(cx, "fpcast");
return llvm::LLVMBuildFPCast(B(cx), Val, DestTy, noname());
}
}
/* Comparisons */
fn ICmp(cx: block, Op: IntPredicate, LHS: ValueRef, RHS: ValueRef)
-> ValueRef {
if cx.unreachable { return llvm::LLVMGetUndef(T_i1()); }
count_insn(cx, "icmp");
return llvm::LLVMBuildICmp(B(cx), Op as c_uint, LHS, RHS, noname());
-> ValueRef {
unsafe {
if cx.unreachable { return llvm::LLVMGetUndef(T_i1()); }
count_insn(cx, "icmp");
return llvm::LLVMBuildICmp(B(cx), Op as c_uint, LHS, RHS, noname());
}
}
fn FCmp(cx: block, Op: RealPredicate, LHS: ValueRef, RHS: ValueRef)
-> ValueRef {
if cx.unreachable { return llvm::LLVMGetUndef(T_i1()); }
count_insn(cx, "fcmp");
return llvm::LLVMBuildFCmp(B(cx), Op as c_uint, LHS, RHS, noname());
-> ValueRef {
unsafe {
if cx.unreachable { return llvm::LLVMGetUndef(T_i1()); }
count_insn(cx, "fcmp");
return llvm::LLVMBuildFCmp(B(cx), Op as c_uint, LHS, RHS, noname());
}
}
/* Miscellaneous instructions */
fn EmptyPhi(cx: block, Ty: TypeRef) -> ValueRef {
if cx.unreachable { return llvm::LLVMGetUndef(Ty); }
count_insn(cx, "emptyphi");
return llvm::LLVMBuildPhi(B(cx), Ty, noname());
unsafe {
if cx.unreachable { return llvm::LLVMGetUndef(Ty); }
count_insn(cx, "emptyphi");
return llvm::LLVMBuildPhi(B(cx), Ty, noname());
}
}
fn Phi(cx: block, Ty: TypeRef, vals: ~[ValueRef], bbs: ~[BasicBlockRef])
-> ValueRef {
if cx.unreachable { return llvm::LLVMGetUndef(Ty); }
assert vals.len() == bbs.len();
let phi = EmptyPhi(cx, Ty);
-> ValueRef {
unsafe {
if cx.unreachable { return llvm::LLVMGetUndef(Ty); }
assert vals.len() == bbs.len();
let phi = EmptyPhi(cx, Ty);
count_insn(cx, "addincoming");
llvm::LLVMAddIncoming(phi, vec::raw::to_ptr(vals),
vec::raw::to_ptr(bbs),
@@ -641,8 +788,8 @@ fn Phi(cx: block, Ty: TypeRef, vals: ~[ValueRef], bbs: ~[BasicBlockRef])
}
fn AddIncomingToPhi(phi: ValueRef, val: ValueRef, bb: BasicBlockRef) {
if llvm::LLVMIsUndef(phi) == lib::llvm::True { return; }
unsafe {
if llvm::LLVMIsUndef(phi) == lib::llvm::True { return; }
let valptr = cast::reinterpret_cast(&ptr::addr_of(&val));
let bbptr = cast::reinterpret_cast(&ptr::addr_of(&bb));
llvm::LLVMAddIncoming(phi, valptr, bbptr, 1 as c_uint);
@@ -650,12 +797,14 @@ fn AddIncomingToPhi(phi: ValueRef, val: ValueRef, bb: BasicBlockRef) {
}
fn _UndefReturn(cx: block, Fn: ValueRef) -> ValueRef {
let ccx = cx.fcx.ccx;
let ty = val_ty(Fn);
let retty = if llvm::LLVMGetTypeKind(ty) == lib::llvm::Integer {
llvm::LLVMGetReturnType(ty) } else { ccx.int_type };
count_insn(cx, ~"");
return llvm::LLVMGetUndef(retty);
unsafe {
let ccx = cx.fcx.ccx;
let ty = val_ty(Fn);
let retty = if llvm::LLVMGetTypeKind(ty) == lib::llvm::Integer {
llvm::LLVMGetReturnType(ty) } else { ccx.int_type };
count_insn(cx, ~"");
return llvm::LLVMGetUndef(retty);
}
}
fn add_span_comment(bcx: block, sp: span, text: ~str) {
@@ -669,18 +818,21 @@ fn add_span_comment(bcx: block, sp: span, text: ~str) {
}
fn add_comment(bcx: block, text: ~str) {
let ccx = bcx.ccx();
if !ccx.sess.no_asm_comments() {
let sanitized = str::replace(text, ~"$", ~"");
let comment_text = ~"# " + str::replace(sanitized, ~"\n", ~"\n\t# ");
let asm = str::as_c_str(comment_text, |c| {
str::as_c_str(~"", |e| {
count_insn(bcx, ~"inlineasm");
llvm::LLVMConstInlineAsm(T_fn(~[], T_void()), c, e,
False, False)
})
});
Call(bcx, asm, ~[]);
unsafe {
let ccx = bcx.ccx();
if !ccx.sess.no_asm_comments() {
let sanitized = str::replace(text, ~"$", ~"");
let comment_text = ~"# " +
str::replace(sanitized, ~"\n", ~"\n\t# ");
let asm = str::as_c_str(comment_text, |c| {
str::as_c_str(~"", |e| {
count_insn(bcx, ~"inlineasm");
llvm::LLVMConstInlineAsm(T_fn(~[], T_void()), c, e,
False, False)
})
});
Call(bcx, asm, ~[]);
}
}
}
@@ -724,120 +876,152 @@ fn CallWithConv(cx: block, Fn: ValueRef, Args: ~[ValueRef],
fn Select(cx: block, If: ValueRef, Then: ValueRef, Else: ValueRef) ->
ValueRef {
if cx.unreachable { return _Undef(Then); }
count_insn(cx, "select");
return llvm::LLVMBuildSelect(B(cx), If, Then, Else, noname());
unsafe {
if cx.unreachable { return _Undef(Then); }
count_insn(cx, "select");
return llvm::LLVMBuildSelect(B(cx), If, Then, Else, noname());
}
}
fn VAArg(cx: block, list: ValueRef, Ty: TypeRef) -> ValueRef {
if cx.unreachable { return llvm::LLVMGetUndef(Ty); }
count_insn(cx, "vaarg");
return llvm::LLVMBuildVAArg(B(cx), list, Ty, noname());
unsafe {
if cx.unreachable { return llvm::LLVMGetUndef(Ty); }
count_insn(cx, "vaarg");
return llvm::LLVMBuildVAArg(B(cx), list, Ty, noname());
}
}
fn ExtractElement(cx: block, VecVal: ValueRef, Index: ValueRef) ->
ValueRef {
if cx.unreachable { return llvm::LLVMGetUndef(T_nil()); }
count_insn(cx, "extractelement");
return llvm::LLVMBuildExtractElement(B(cx), VecVal, Index, noname());
unsafe {
if cx.unreachable { return llvm::LLVMGetUndef(T_nil()); }
count_insn(cx, "extractelement");
return llvm::LLVMBuildExtractElement(B(cx), VecVal, Index, noname());
}
}
fn InsertElement(cx: block, VecVal: ValueRef, EltVal: ValueRef,
Index: ValueRef) {
if cx.unreachable { return; }
count_insn(cx, "insertelement");
llvm::LLVMBuildInsertElement(B(cx), VecVal, EltVal, Index, noname());
unsafe {
if cx.unreachable { return; }
count_insn(cx, "insertelement");
llvm::LLVMBuildInsertElement(B(cx), VecVal, EltVal, Index, noname());
}
}
fn ShuffleVector(cx: block, V1: ValueRef, V2: ValueRef,
Mask: ValueRef) {
if cx.unreachable { return; }
count_insn(cx, "shufflevector");
llvm::LLVMBuildShuffleVector(B(cx), V1, V2, Mask, noname());
unsafe {
if cx.unreachable { return; }
count_insn(cx, "shufflevector");
llvm::LLVMBuildShuffleVector(B(cx), V1, V2, Mask, noname());
}
}
fn ExtractValue(cx: block, AggVal: ValueRef, Index: uint) -> ValueRef {
if cx.unreachable { return llvm::LLVMGetUndef(T_nil()); }
count_insn(cx, "extractvalue");
return llvm::LLVMBuildExtractValue(
B(cx), AggVal, Index as c_uint, noname());
unsafe {
if cx.unreachable { return llvm::LLVMGetUndef(T_nil()); }
count_insn(cx, "extractvalue");
return llvm::LLVMBuildExtractValue(
B(cx), AggVal, Index as c_uint, noname());
}
}
fn InsertValue(cx: block, AggVal: ValueRef, EltVal: ValueRef,
Index: uint) {
if cx.unreachable { return; }
count_insn(cx, "insertvalue");
llvm::LLVMBuildInsertValue(B(cx), AggVal, EltVal, Index as c_uint,
noname());
unsafe {
if cx.unreachable { return; }
count_insn(cx, "insertvalue");
llvm::LLVMBuildInsertValue(B(cx), AggVal, EltVal, Index as c_uint,
noname());
}
}
fn IsNull(cx: block, Val: ValueRef) -> ValueRef {
if cx.unreachable { return llvm::LLVMGetUndef(T_i1()); }
count_insn(cx, "isnull");
return llvm::LLVMBuildIsNull(B(cx), Val, noname());
unsafe {
if cx.unreachable { return llvm::LLVMGetUndef(T_i1()); }
count_insn(cx, "isnull");
return llvm::LLVMBuildIsNull(B(cx), Val, noname());
}
}
fn IsNotNull(cx: block, Val: ValueRef) -> ValueRef {
if cx.unreachable { return llvm::LLVMGetUndef(T_i1()); }
count_insn(cx, "isnotnull");
return llvm::LLVMBuildIsNotNull(B(cx), Val, noname());
unsafe {
if cx.unreachable { return llvm::LLVMGetUndef(T_i1()); }
count_insn(cx, "isnotnull");
return llvm::LLVMBuildIsNotNull(B(cx), Val, noname());
}
}
fn PtrDiff(cx: block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
let ccx = cx.fcx.ccx;
if cx.unreachable { return llvm::LLVMGetUndef(ccx.int_type); }
count_insn(cx, "ptrdiff");
return llvm::LLVMBuildPtrDiff(B(cx), LHS, RHS, noname());
unsafe {
let ccx = cx.fcx.ccx;
if cx.unreachable { return llvm::LLVMGetUndef(ccx.int_type); }
count_insn(cx, "ptrdiff");
return llvm::LLVMBuildPtrDiff(B(cx), LHS, RHS, noname());
}
}
fn Trap(cx: block) {
if cx.unreachable { return; }
let b = B(cx);
let BB: BasicBlockRef = llvm::LLVMGetInsertBlock(b);
let FN: ValueRef = llvm::LLVMGetBasicBlockParent(BB);
let M: ModuleRef = llvm::LLVMGetGlobalParent(FN);
let T: ValueRef = str::as_c_str(~"llvm.trap", |buf| {
llvm::LLVMGetNamedFunction(M, buf)
});
assert (T as int != 0);
let Args: ~[ValueRef] = ~[];
unsafe {
count_insn(cx, "trap");
llvm::LLVMBuildCall(b, T, vec::raw::to_ptr(Args),
Args.len() as c_uint, noname());
if cx.unreachable { return; }
let b = B(cx);
let BB: BasicBlockRef = llvm::LLVMGetInsertBlock(b);
let FN: ValueRef = llvm::LLVMGetBasicBlockParent(BB);
let M: ModuleRef = llvm::LLVMGetGlobalParent(FN);
let T: ValueRef = str::as_c_str(~"llvm.trap", |buf| {
llvm::LLVMGetNamedFunction(M, buf)
});
assert (T as int != 0);
let Args: ~[ValueRef] = ~[];
unsafe {
count_insn(cx, "trap");
llvm::LLVMBuildCall(b, T, vec::raw::to_ptr(Args),
Args.len() as c_uint, noname());
}
}
}
fn LandingPad(cx: block, Ty: TypeRef, PersFn: ValueRef,
NumClauses: uint) -> ValueRef {
assert !cx.terminated && !cx.unreachable;
count_insn(cx, "landingpad");
return llvm::LLVMBuildLandingPad(B(cx), Ty, PersFn,
NumClauses as c_uint, noname());
unsafe {
assert !cx.terminated && !cx.unreachable;
count_insn(cx, "landingpad");
return llvm::LLVMBuildLandingPad(B(cx), Ty, PersFn,
NumClauses as c_uint, noname());
}
}
fn SetCleanup(cx: block, LandingPad: ValueRef) {
count_insn(cx, "setcleanup");
llvm::LLVMSetCleanup(LandingPad, lib::llvm::True);
unsafe {
count_insn(cx, "setcleanup");
llvm::LLVMSetCleanup(LandingPad, lib::llvm::True);
}
}
fn Resume(cx: block, Exn: ValueRef) -> ValueRef {
assert (!cx.terminated);
cx.terminated = true;
count_insn(cx, "resume");
return llvm::LLVMBuildResume(B(cx), Exn);
unsafe {
assert (!cx.terminated);
cx.terminated = true;
count_insn(cx, "resume");
return llvm::LLVMBuildResume(B(cx), Exn);
}
}
// Atomic Operations
fn AtomicCmpXchg(cx: block, dst: ValueRef,
cmp: ValueRef, src: ValueRef,
order: AtomicOrdering) -> ValueRef {
llvm::LLVMBuildAtomicCmpXchg(B(cx), dst, cmp, src, order)
unsafe {
llvm::LLVMBuildAtomicCmpXchg(B(cx), dst, cmp, src, order)
}
}
fn AtomicRMW(cx: block, op: AtomicBinOp,
dst: ValueRef, src: ValueRef,
order: AtomicOrdering) -> ValueRef {
llvm::LLVMBuildAtomicRMW(B(cx), op, dst, src, order)
unsafe {
llvm::LLVMBuildAtomicRMW(B(cx), op, dst, src, order)
}
}
//
+31 -23
View File
@@ -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 {
+3 -1
View File
@@ -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
}
+157 -89
View File
@@ -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);
cx.const_cstr_cache.insert(s, g);
return g;
}
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);
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
+369 -346
View File
@@ -59,41 +59,49 @@ fn const_lit(cx: @crate_ctxt, e: @ast::expr, lit: ast::lit)
}
fn const_ptrcast(cx: @crate_ctxt, a: ValueRef, t: TypeRef) -> ValueRef {
let b = llvm::LLVMConstPointerCast(a, T_ptr(t));
assert cx.const_globals.insert(b as int, a);
b
unsafe {
let b = llvm::LLVMConstPointerCast(a, T_ptr(t));
assert cx.const_globals.insert(b as int, a);
b
}
}
fn const_vec(cx: @crate_ctxt, e: @ast::expr, es: &[@ast::expr])
-> (ValueRef, ValueRef, TypeRef) {
let vec_ty = ty::expr_ty(cx.tcx, e);
let unit_ty = ty::sequence_element_type(cx.tcx, vec_ty);
let llunitty = type_of::type_of(cx, unit_ty);
let v = C_array(llunitty, es.map(|e| const_expr(cx, *e)));
let unit_sz = shape::llsize_of(cx, llunitty);
let sz = llvm::LLVMConstMul(C_uint(cx, es.len()), unit_sz);
return (v, sz, llunitty);
unsafe {
let vec_ty = ty::expr_ty(cx.tcx, e);
let unit_ty = ty::sequence_element_type(cx.tcx, vec_ty);
let llunitty = type_of::type_of(cx, unit_ty);
let v = C_array(llunitty, es.map(|e| const_expr(cx, *e)));
let unit_sz = shape::llsize_of(cx, llunitty);
let sz = llvm::LLVMConstMul(C_uint(cx, es.len()), unit_sz);
return (v, sz, llunitty);
}
}
fn const_deref(cx: @crate_ctxt, v: ValueRef) -> ValueRef {
let v = match cx.const_globals.find(v as int) {
Some(v) => v,
None => v
};
assert llvm::LLVMIsGlobalConstant(v) == True;
let v = llvm::LLVMGetInitializer(v);
v
unsafe {
let v = match cx.const_globals.find(v as int) {
Some(v) => v,
None => v
};
assert llvm::LLVMIsGlobalConstant(v) == True;
let v = llvm::LLVMGetInitializer(v);
v
}
}
fn const_get_elt(cx: @crate_ctxt, v: ValueRef, us: &[c_uint]) -> ValueRef {
let r = do vec::as_imm_buf(us) |p, len| {
llvm::LLVMConstExtractValue(v, p, len as c_uint)
};
unsafe {
let r = do vec::as_imm_buf(us) |p, len| {
llvm::LLVMConstExtractValue(v, p, len as c_uint)
};
debug!("const_get_elt(v=%s, us=%?, r=%s)",
val_str(cx.tn, v), us, val_str(cx.tn, r));
debug!("const_get_elt(v=%s, us=%?, r=%s)",
val_str(cx.tn, v), us, val_str(cx.tn, r));
return r;
return r;
}
}
fn const_autoderef(cx: @crate_ctxt, ty: ty::t, v: ValueRef)
@@ -130,345 +138,360 @@ fn get_const_val(cx: @crate_ctxt, def_id: ast::def_id) -> ValueRef {
}
fn const_expr(cx: @crate_ctxt, e: @ast::expr) -> ValueRef {
let _icx = cx.insn_ctxt("const_expr");
return match /*bad*/copy e.node {
ast::expr_lit(lit) => consts::const_lit(cx, e, *lit),
ast::expr_binary(b, e1, e2) => {
let te1 = const_expr(cx, e1);
let te2 = const_expr(cx, e2);
unsafe {
let _icx = cx.insn_ctxt("const_expr");
return match /*bad*/copy e.node {
ast::expr_lit(lit) => consts::const_lit(cx, e, *lit),
ast::expr_binary(b, e1, e2) => {
let te1 = const_expr(cx, e1);
let te2 = const_expr(cx, e2);
let te2 = base::cast_shift_const_rhs(b, te1, te2);
let te2 = base::cast_shift_const_rhs(b, te1, te2);
/* Neither type is bottom, and we expect them to be unified already,
* so the following is safe. */
let ty = ty::expr_ty(cx.tcx, e1);
let is_float = ty::type_is_fp(ty);
let signed = ty::type_is_signed(ty);
return match b {
ast::add => {
if is_float { llvm::LLVMConstFAdd(te1, te2) }
else { llvm::LLVMConstAdd(te1, te2) }
}
ast::subtract => {
if is_float { llvm::LLVMConstFSub(te1, te2) }
else { llvm::LLVMConstSub(te1, te2) }
}
ast::mul => {
if is_float { llvm::LLVMConstFMul(te1, te2) }
else { llvm::LLVMConstMul(te1, te2) }
}
ast::div => {
if is_float { llvm::LLVMConstFDiv(te1, te2) }
else if signed { llvm::LLVMConstSDiv(te1, te2) }
else { llvm::LLVMConstUDiv(te1, te2) }
}
ast::rem => {
if is_float { llvm::LLVMConstFRem(te1, te2) }
else if signed { llvm::LLVMConstSRem(te1, te2) }
else { llvm::LLVMConstURem(te1, te2) }
}
ast::and |
ast::or => cx.sess.span_unimpl(e.span, ~"binop logic"),
ast::bitxor => llvm::LLVMConstXor(te1, te2),
ast::bitand => llvm::LLVMConstAnd(te1, te2),
ast::bitor => llvm::LLVMConstOr(te1, te2),
ast::shl => llvm::LLVMConstShl(te1, te2),
ast::shr => {
if signed { llvm::LLVMConstAShr(te1, te2) }
else { llvm::LLVMConstLShr(te1, te2) }
}
ast::eq |
ast::lt |
ast::le |
ast::ne |
ast::ge |
ast::gt => cx.sess.span_unimpl(e.span, ~"binop comparator")
}
}
ast::expr_unary(u, e) => {
let te = const_expr(cx, e);
let ty = ty::expr_ty(cx.tcx, e);
let is_float = ty::type_is_fp(ty);
return match u {
ast::box(_) |
ast::uniq(_) |
ast::deref => const_deref(cx, te),
ast::not => llvm::LLVMConstNot(te),
ast::neg => {
if is_float { llvm::LLVMConstFNeg(te) }
else { llvm::LLVMConstNeg(te) }
}
}
}
ast::expr_field(base, field, _) => {
let bt = ty::expr_ty(cx.tcx, base);
let bv = const_expr(cx, base);
let (bt, bv) = const_autoderef(cx, bt, bv);
do expr::with_field_tys(cx.tcx, bt, None) |_has_dtor, field_tys| {
let ix = ty::field_idx_strict(cx.tcx, field, field_tys);
// Note: ideally, we'd use `struct_field()` here instead
// of hardcoding [0, ix], but we can't because it yields
// the wrong type and also inserts an extra 0 that is
// not needed in the constant variety:
const_get_elt(cx, bv, [0, ix as c_uint])
}
}
ast::expr_index(base, index) => {
let bt = ty::expr_ty(cx.tcx, base);
let bv = const_expr(cx, base);
let (bt, bv) = const_autoderef(cx, bt, bv);
let iv = match const_eval::eval_const_expr(cx.tcx, index) {
const_eval::const_int(i) => i as u64,
const_eval::const_uint(u) => u,
_ => cx.sess.span_bug(index.span,
~"index is not an integer-constant \
expression")
};
let (arr, _len) = match ty::get(bt).sty {
ty::ty_evec(_, vstore) | ty::ty_estr(vstore) =>
match vstore {
ty::vstore_fixed(u) =>
(bv, C_uint(cx, u)),
ty::vstore_slice(_) => {
let unit_ty = ty::sequence_element_type(cx.tcx, bt);
let llunitty = type_of::type_of(cx, unit_ty);
let unit_sz = shape::llsize_of(cx, llunitty);
(const_deref(cx, const_get_elt(cx, bv, [0])),
llvm::LLVMConstUDiv(const_get_elt(cx, bv, [1]),
unit_sz))
},
_ => cx.sess.span_bug(base.span,
~"index-expr base must be \
fixed-size or slice")
},
_ => cx.sess.span_bug(base.span,
~"index-expr base must be \
a vector or string type")
};
// FIXME #3169: This is a little odd but it arises due to a weird
// wrinkle in LLVM: it doesn't appear willing to let us call
// LLVMConstIntGetZExtValue on the size element of the slice, or
// seemingly any integer-const involving a sizeof() call. Despite
// that being "a const", it's not the kind of const you can ask
// for the integer-value of, evidently. This might be an LLVM
// bug, not sure. In any case, to work around this we drop down
// to the array-type level here and just ask how long the
// array-type itself is, ignoring the length we pulled out of the
// slice. This in turn only works because we picked out the
// original globalvar via const_deref and so can recover the
// array-size of the underlying array, and all this will hold
// together exactly as long as we _don't_ support const
// sub-slices (that is, slices that represent something other
// than a whole array). At that point we'll have more and uglier
// work to do here, but for now this should work.
//
// In the future, what we should be doing here is the
// moral equivalent of:
//
// let len = llvm::LLVMConstIntGetZExtValue(len) as u64;
//
// but we might have to do substantially more magic to
// make it work. Or figure out what is causing LLVM to
// not want to consider sizeof() a constant expression
// we can get the value (as a number) out of.
let len = llvm::LLVMGetArrayLength(val_ty(arr)) as u64;
let len = match ty::get(bt).sty {
ty::ty_estr(*) => {assert len > 0; len - 1},
_ => len
};
if iv >= len {
// FIXME #3170: report this earlier on in the const-eval
// pass. Reporting here is a bit late.
cx.sess.span_err(e.span,
~"const index-expr is out of bounds");
}
const_get_elt(cx, arr, [iv as c_uint])
}
ast::expr_cast(base, _) => {
let ety = ty::expr_ty(cx.tcx, e), llty = type_of::type_of(cx, ety);
let basety = ty::expr_ty(cx.tcx, base);
let v = const_expr(cx, base);
match (expr::cast_type_kind(basety),
expr::cast_type_kind(ety)) {
(expr::cast_integral, expr::cast_integral) => {
let s = if ty::type_is_signed(basety) { True } else { False };
llvm::LLVMConstIntCast(v, llty, s)
}
(expr::cast_integral, expr::cast_float) => {
if ty::type_is_signed(basety) { llvm::LLVMConstSIToFP(v, llty) }
else { llvm::LLVMConstUIToFP(v, llty) }
}
(expr::cast_float, expr::cast_float) => {
llvm::LLVMConstFPCast(v, llty)
}
(expr::cast_float, expr::cast_integral) => {
if ty::type_is_signed(ety) { llvm::LLVMConstFPToSI(v, llty) }
else { llvm::LLVMConstFPToUI(v, llty) }
}
_ => cx.sess.impossible_case(e.span,
~"bad combination of types for cast")
}
}
ast::expr_addr_of(ast::m_imm, sub) => {
let cv = const_expr(cx, sub);
let subty = ty::expr_ty(cx.tcx, sub),
llty = type_of::type_of(cx, subty);
let gv = do str::as_c_str("const") |name| {
llvm::LLVMAddGlobal(cx.llmod, llty, name)
};
llvm::LLVMSetInitializer(gv, cv);
llvm::LLVMSetGlobalConstant(gv, True);
gv
}
ast::expr_tup(es) => {
C_struct(es.map(|e| const_expr(cx, *e)))
}
ast::expr_rec(ref fs, None) => {
C_struct([C_struct(
(*fs).map(|f| const_expr(cx, f.node.expr)))])
}
ast::expr_struct(_, ref fs, _) => {
let ety = ty::expr_ty(cx.tcx, e);
let cs = do expr::with_field_tys(cx.tcx,
ety,
None) |_hd, field_tys| {
field_tys.map(|field_ty| {
match fs.find(|f| field_ty.ident == f.node.ident) {
Some(ref f) => const_expr(cx, (*f).node.expr),
None => {
cx.tcx.sess.span_bug(
e.span, ~"missing struct field");
}
}
})
};
let llty = type_of::type_of(cx, ety);
C_named_struct(llty, [C_struct(cs)])
}
ast::expr_vec(es, ast::m_imm) => {
let (v, _, _) = const_vec(cx, e, es);
v
}
ast::expr_vstore(e, ast::expr_vstore_fixed(_)) => {
const_expr(cx, e)
}
ast::expr_vstore(sub, ast::expr_vstore_slice) => {
match /*bad*/copy sub.node {
ast::expr_lit(lit) => {
match lit.node {
ast::lit_str(*) => { const_expr(cx, sub) }
_ => { cx.sess.span_bug(e.span,
~"bad const-slice lit") }
/* Neither type is bottom, and we expect them to be unified
* already, so the following is safe. */
let ty = ty::expr_ty(cx.tcx, e1);
let is_float = ty::type_is_fp(ty);
let signed = ty::type_is_signed(ty);
return match b {
ast::add => {
if is_float { llvm::LLVMConstFAdd(te1, te2) }
else { llvm::LLVMConstAdd(te1, te2) }
}
ast::subtract => {
if is_float { llvm::LLVMConstFSub(te1, te2) }
else { llvm::LLVMConstSub(te1, te2) }
}
ast::mul => {
if is_float { llvm::LLVMConstFMul(te1, te2) }
else { llvm::LLVMConstMul(te1, te2) }
}
ast::div => {
if is_float { llvm::LLVMConstFDiv(te1, te2) }
else if signed { llvm::LLVMConstSDiv(te1, te2) }
else { llvm::LLVMConstUDiv(te1, te2) }
}
ast::rem => {
if is_float { llvm::LLVMConstFRem(te1, te2) }
else if signed { llvm::LLVMConstSRem(te1, te2) }
else { llvm::LLVMConstURem(te1, te2) }
}
ast::and |
ast::or => cx.sess.span_unimpl(e.span, ~"binop logic"),
ast::bitxor => llvm::LLVMConstXor(te1, te2),
ast::bitand => llvm::LLVMConstAnd(te1, te2),
ast::bitor => llvm::LLVMConstOr(te1, te2),
ast::shl => llvm::LLVMConstShl(te1, te2),
ast::shr => {
if signed { llvm::LLVMConstAShr(te1, te2) }
else { llvm::LLVMConstLShr(te1, te2) }
}
ast::eq |
ast::lt |
ast::le |
ast::ne |
ast::ge |
ast::gt => cx.sess.span_unimpl(e.span, ~"binop comparator")
}
}
ast::expr_vec(es, ast::m_imm) => {
let (cv, sz, llunitty) = const_vec(cx, e, es);
let llty = val_ty(cv);
ast::expr_unary(u, e) => {
let te = const_expr(cx, e);
let ty = ty::expr_ty(cx.tcx, e);
let is_float = ty::type_is_fp(ty);
return match u {
ast::box(_) |
ast::uniq(_) |
ast::deref => const_deref(cx, te),
ast::not => llvm::LLVMConstNot(te),
ast::neg => {
if is_float { llvm::LLVMConstFNeg(te) }
else { llvm::LLVMConstNeg(te) }
}
}
}
ast::expr_field(base, field, _) => {
let bt = ty::expr_ty(cx.tcx, base);
let bv = const_expr(cx, base);
let (bt, bv) = const_autoderef(cx, bt, bv);
do expr::with_field_tys(cx.tcx, bt, None) |_, field_tys| {
let ix = ty::field_idx_strict(cx.tcx, field, field_tys);
// Note: ideally, we'd use `struct_field()` here instead
// of hardcoding [0, ix], but we can't because it yields
// the wrong type and also inserts an extra 0 that is
// not needed in the constant variety:
const_get_elt(cx, bv, [0, ix as c_uint])
}
}
ast::expr_index(base, index) => {
let bt = ty::expr_ty(cx.tcx, base);
let bv = const_expr(cx, base);
let (bt, bv) = const_autoderef(cx, bt, bv);
let iv = match const_eval::eval_const_expr(cx.tcx, index) {
const_eval::const_int(i) => i as u64,
const_eval::const_uint(u) => u,
_ => cx.sess.span_bug(index.span,
~"index is not an integer-constant \
expression")
};
let (arr, _len) = match ty::get(bt).sty {
ty::ty_evec(_, vstore) | ty::ty_estr(vstore) =>
match vstore {
ty::vstore_fixed(u) =>
(bv, C_uint(cx, u)),
ty::vstore_slice(_) => {
let unit_ty = ty::sequence_element_type(cx.tcx, bt);
let llunitty = type_of::type_of(cx, unit_ty);
let unit_sz = shape::llsize_of(cx, llunitty);
(const_deref(cx, const_get_elt(cx, bv, [0])),
llvm::LLVMConstUDiv(const_get_elt(cx, bv, [1]),
unit_sz))
},
_ => cx.sess.span_bug(base.span,
~"index-expr base must be \
fixed-size or slice")
},
_ => cx.sess.span_bug(base.span,
~"index-expr base must be \
a vector or string type")
};
// FIXME #3169: This is a little odd but it arises due to a
// weird wrinkle in LLVM: it doesn't appear willing to let us
// call LLVMConstIntGetZExtValue on the size element of the
// slice, or seemingly any integer-const involving a sizeof()
// call. Despite that being "a const", it's not the kind of
// const you can ask for the integer-value of, evidently. This
// might be an LLVM bug, not sure. In any case, to work around
// this we drop down to the array-type level here and just ask
// how long the array-type itself is, ignoring the length we
// pulled out of the slice. This in turn only works because we
// picked out the original globalvar via const_deref and so can
// recover the array-size of the underlying array, and all this
// will hold together exactly as long as we _don't_ support
// const sub-slices (that is, slices that represent something
// other than a whole array). At that point we'll have more and
// uglier work to do here, but for now this should work.
//
// In the future, what we should be doing here is the
// moral equivalent of:
//
// let len = llvm::LLVMConstIntGetZExtValue(len) as u64;
//
// but we might have to do substantially more magic to
// make it work. Or figure out what is causing LLVM to
// not want to consider sizeof() a constant expression
// we can get the value (as a number) out of.
let len = llvm::LLVMGetArrayLength(val_ty(arr)) as u64;
let len = match ty::get(bt).sty {
ty::ty_estr(*) => {assert len > 0; len - 1},
_ => len
};
if iv >= len {
// FIXME #3170: report this earlier on in the const-eval
// pass. Reporting here is a bit late.
cx.sess.span_err(e.span,
~"const index-expr is out of bounds");
}
const_get_elt(cx, arr, [iv as c_uint])
}
ast::expr_cast(base, _) => {
let ety = ty::expr_ty(cx.tcx, e);
let llty = type_of::type_of(cx, ety);
let basety = ty::expr_ty(cx.tcx, base);
let v = const_expr(cx, base);
match (expr::cast_type_kind(basety),
expr::cast_type_kind(ety)) {
(expr::cast_integral, expr::cast_integral) => {
let s = if ty::type_is_signed(basety) { True } else { False };
llvm::LLVMConstIntCast(v, llty, s)
}
(expr::cast_integral, expr::cast_float) => {
if ty::type_is_signed(basety) {
llvm::LLVMConstSIToFP(v, llty)
} else {
llvm::LLVMConstUIToFP(v, llty)
}
}
(expr::cast_float, expr::cast_float) => {
llvm::LLVMConstFPCast(v, llty)
}
(expr::cast_float, expr::cast_integral) => {
if ty::type_is_signed(ety) { llvm::LLVMConstFPToSI(v, llty) }
else { llvm::LLVMConstFPToUI(v, llty) }
}
_ => {
cx.sess.impossible_case(e.span,
~"bad combination of types for cast")
}
}
}
ast::expr_addr_of(ast::m_imm, sub) => {
let cv = const_expr(cx, sub);
let subty = ty::expr_ty(cx.tcx, sub),
llty = type_of::type_of(cx, subty);
let gv = do str::as_c_str("const") |name| {
llvm::LLVMAddGlobal(cx.llmod, llty, name)
};
llvm::LLVMSetInitializer(gv, cv);
llvm::LLVMSetGlobalConstant(gv, True);
let p = const_ptrcast(cx, gv, llunitty);
C_struct(~[p, sz])
gv
}
_ => cx.sess.span_bug(e.span,
~"bad const-slice expr")
}
}
ast::expr_path(pth) => {
assert pth.types.len() == 0;
match cx.tcx.def_map.find(e.id) {
Some(ast::def_fn(def_id, _)) => {
assert ast_util::is_local(def_id);
let f = base::get_item_val(cx, def_id.node);
C_struct(~[f, C_null(T_opaque_box_ptr(cx))])
}
Some(ast::def_const(def_id)) => {
get_const_val(cx, def_id)
}
Some(ast::def_variant(enum_did, variant_did)) => {
// Note that we know this is a C-like (nullary) enum variant,
// or we wouldn't have gotten here -- the constant checker
// forbids paths that don't map to C-like enum variants.
let ety = ty::expr_ty(cx.tcx, e);
let llty = type_of::type_of(cx, ety);
// Can't use `discrims` from the crate context here because
// those discriminants have an extra level of indirection,
// and there's no LLVM constant load instruction.
let mut lldiscrim_opt = None;
for ty::enum_variants(cx.tcx, enum_did).each |variant_info| {
if variant_info.id == variant_did {
lldiscrim_opt = Some(C_int(cx,
variant_info.disr_val));
break;
}
ast::expr_tup(es) => {
C_struct(es.map(|e| const_expr(cx, *e)))
}
ast::expr_rec(ref fs, None) => {
C_struct([C_struct(
(*fs).map(|f| const_expr(cx, f.node.expr)))])
}
ast::expr_struct(_, ref fs, _) => {
let ety = ty::expr_ty(cx.tcx, e);
let cs = do expr::with_field_tys(cx.tcx,
ety,
None) |_hd, field_tys| {
field_tys.map(|field_ty| {
match fs.find(|f| field_ty.ident == f.node.ident) {
Some(ref f) => const_expr(cx, (*f).node.expr),
None => {
cx.tcx.sess.span_bug(
e.span, ~"missing struct field");
}
}
})
};
let llty = type_of::type_of(cx, ety);
C_named_struct(llty, [C_struct(cs)])
}
ast::expr_vec(es, ast::m_imm) => {
let (v, _, _) = const_vec(cx, e, es);
v
}
ast::expr_vstore(e, ast::expr_vstore_fixed(_)) => {
const_expr(cx, e)
}
ast::expr_vstore(sub, ast::expr_vstore_slice) => {
match /*bad*/copy sub.node {
ast::expr_lit(lit) => {
match lit.node {
ast::lit_str(*) => { const_expr(cx, sub) }
_ => { cx.sess.span_bug(e.span,
~"bad const-slice lit") }
}
let lldiscrim;
match lldiscrim_opt {
None => {
cx.tcx.sess.span_bug(e.span,
~"didn't find discriminant?!");
}
Some(found_lldiscrim) => {
lldiscrim = found_lldiscrim;
}
}
let fields = if ty::enum_is_univariant(cx.tcx, enum_did) {
~[lldiscrim]
} else {
let llstructtys = lib::llvm::struct_element_types(llty);
~[lldiscrim, C_null(llstructtys[1])]
}
ast::expr_vec(es, ast::m_imm) => {
let (cv, sz, llunitty) = const_vec(cx, e, es);
let llty = val_ty(cv);
let gv = do str::as_c_str("const") |name| {
llvm::LLVMAddGlobal(cx.llmod, llty, name)
};
llvm::LLVMSetInitializer(gv, cv);
llvm::LLVMSetGlobalConstant(gv, True);
let p = const_ptrcast(cx, gv, llunitty);
C_struct(~[p, sz])
}
_ => cx.sess.span_bug(e.span,
~"bad const-slice expr")
}
}
ast::expr_path(pth) => {
assert pth.types.len() == 0;
match cx.tcx.def_map.find(e.id) {
Some(ast::def_fn(def_id, _)) => {
assert ast_util::is_local(def_id);
let f = base::get_item_val(cx, def_id.node);
C_struct(~[f, C_null(T_opaque_box_ptr(cx))])
}
Some(ast::def_const(def_id)) => {
get_const_val(cx, def_id)
}
Some(ast::def_variant(enum_did, variant_did)) => {
// Note that we know this is a C-like (nullary) enum
// variant or we wouldn't have gotten here -- the constant
// checker forbids paths that don't map to C-like enum
// variants.
let ety = ty::expr_ty(cx.tcx, e);
let llty = type_of::type_of(cx, ety);
C_named_struct(llty, fields)
}
Some(ast::def_struct(_)) => {
let ety = ty::expr_ty(cx.tcx, e);
let llty = type_of::type_of(cx, ety);
C_null(llty)
}
_ => {
cx.sess.span_bug(e.span,
~"expected a const, fn, or variant def")
}
}
}
ast::expr_call(callee, args, _) => {
match cx.tcx.def_map.find(callee.id) {
Some(ast::def_struct(def_id)) => {
let ety = ty::expr_ty(cx.tcx, e);
let llty = type_of::type_of(cx, ety);
let llstructbody = C_struct(args.map(|a| const_expr(cx, *a)));
if ty::ty_dtor(cx.tcx, def_id).is_present() {
C_named_struct(llty, ~[ llstructbody, C_u8(0) ])
} else {
C_named_struct(llty, ~[ llstructbody ])
// Can't use `discrims` from the crate context here
// because those discriminants have an extra level of
// indirection, and there's no LLVM constant load
// instruction.
let mut lldiscrim_opt = None;
for ty::enum_variants(cx.tcx, enum_did).each
|variant_info| {
if variant_info.id == variant_did {
lldiscrim_opt = Some(C_int(cx,
variant_info.disr_val));
break;
}
}
let lldiscrim;
match lldiscrim_opt {
None => {
cx.tcx.sess.span_bug(e.span,
~"didn't find discriminant?!");
}
Some(found_lldiscrim) => {
lldiscrim = found_lldiscrim;
}
}
let fields = if ty::enum_is_univariant(cx.tcx, enum_did) {
~[lldiscrim]
} else {
let llstructtys =
lib::llvm::struct_element_types(llty);
~[lldiscrim, C_null(llstructtys[1])]
};
C_named_struct(llty, fields)
}
Some(ast::def_struct(_)) => {
let ety = ty::expr_ty(cx.tcx, e);
let llty = type_of::type_of(cx, ety);
C_null(llty)
}
_ => {
cx.sess.span_bug(e.span,
~"expected a const, fn, or variant def")
}
}
_ => cx.sess.span_bug(e.span, ~"expected a struct def")
}
}
ast::expr_paren(e) => { return const_expr(cx, e); }
_ => cx.sess.span_bug(e.span,
~"bad constant expression type in consts::const_expr")
};
}
ast::expr_call(callee, args, _) => {
match cx.tcx.def_map.find(callee.id) {
Some(ast::def_struct(def_id)) => {
let ety = ty::expr_ty(cx.tcx, e);
let llty = type_of::type_of(cx, ety);
let llstructbody =
C_struct(args.map(|a| const_expr(cx, *a)));
if ty::ty_dtor(cx.tcx, def_id).is_present() {
C_named_struct(llty, ~[ llstructbody, C_u8(0) ])
} else {
C_named_struct(llty, ~[ llstructbody ])
}
}
_ => cx.sess.span_bug(e.span, ~"expected a struct def")
}
}
ast::expr_paren(e) => { return const_expr(cx, e); }
_ => cx.sess.span_bug(e.span,
~"bad constant expression type in consts::const_expr")
};
}
}
fn trans_const(ccx: @crate_ctxt, e: @ast::expr, id: ast::node_id) {
let _icx = ccx.insn_ctxt("trans_const");
let g = base::get_item_val(ccx, id);
let v = const_expr(ccx, e);
ccx.const_values.insert(id, v);
llvm::LLVMSetInitializer(g, v);
llvm::LLVMSetGlobalConstant(g, True);
unsafe {
let _icx = ccx.insn_ctxt("trans_const");
let g = base::get_item_val(ccx, id);
let v = const_expr(ccx, e);
ccx.const_values.insert(id, v);
llvm::LLVMSetInitializer(g, v);
llvm::LLVMSetGlobalConstant(g, True);
}
}
+9 -6
View File
@@ -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
};
+13 -5
View File
@@ -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> {
+13 -9
View File
@@ -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,
+174 -156
View File
@@ -92,56 +92,62 @@ fn align(off: uint, ty: TypeRef) -> uint {
}
fn struct_tys(ty: TypeRef) -> ~[TypeRef] {
let n = llvm::LLVMCountStructElementTypes(ty);
let mut elts = vec::from_elem(n as uint, ptr::null());
llvm::LLVMGetStructElementTypes(ty,
ptr::to_mut_unsafe_ptr(&mut elts[0]));
return elts;
unsafe {
let n = llvm::LLVMCountStructElementTypes(ty);
let mut elts = vec::from_elem(n as uint, ptr::null());
llvm::LLVMGetStructElementTypes(ty,
ptr::to_mut_unsafe_ptr(&mut elts[0]));
return elts;
}
}
fn ty_align(ty: TypeRef) -> uint {
return match llvm::LLVMGetTypeKind(ty) {
Integer => {
((llvm::LLVMGetIntTypeWidth(ty) as uint) + 7) / 8
}
Pointer => 8,
Float => 4,
Double => 8,
Struct => {
do vec::foldl(0, struct_tys(ty)) |a, t| {
uint::max(a, ty_align(*t))
}
}
Array => {
let elt = llvm::LLVMGetElementType(ty);
ty_align(elt)
}
_ => fail ~"ty_size: unhandled type"
};
unsafe {
return match llvm::LLVMGetTypeKind(ty) {
Integer => {
((llvm::LLVMGetIntTypeWidth(ty) as uint) + 7) / 8
}
Pointer => 8,
Float => 4,
Double => 8,
Struct => {
do vec::foldl(0, struct_tys(ty)) |a, t| {
uint::max(a, ty_align(*t))
}
}
Array => {
let elt = llvm::LLVMGetElementType(ty);
ty_align(elt)
}
_ => fail ~"ty_size: unhandled type"
};
}
}
fn ty_size(ty: TypeRef) -> uint {
return match llvm::LLVMGetTypeKind(ty) {
Integer => {
((llvm::LLVMGetIntTypeWidth(ty) as uint) + 7) / 8
}
Pointer => 8,
Float => 4,
Double => 8,
Struct => {
let size = do vec::foldl(0, struct_tys(ty)) |s, t| {
align(s, *t) + ty_size(*t)
};
align(size, ty)
}
Array => {
let len = llvm::LLVMGetArrayLength(ty) as uint;
let elt = llvm::LLVMGetElementType(ty);
let eltsz = ty_size(elt);
len * eltsz
}
_ => fail ~"ty_size: unhandled type"
};
unsafe {
return match llvm::LLVMGetTypeKind(ty) {
Integer => {
((llvm::LLVMGetIntTypeWidth(ty) as uint) + 7) / 8
}
Pointer => 8,
Float => 4,
Double => 8,
Struct => {
let size = do vec::foldl(0, struct_tys(ty)) |s, t| {
align(s, *t) + ty_size(*t)
};
align(size, ty)
}
Array => {
let len = llvm::LLVMGetArrayLength(ty) as uint;
let elt = llvm::LLVMGetElementType(ty);
let eltsz = ty_size(elt);
len * eltsz
}
_ => fail ~"ty_size: unhandled type"
};
}
}
fn all_mem(cls: &[mut x86_64_reg_class]) {
@@ -193,94 +199,98 @@ fn classify_struct(tys: &[TypeRef],
fn classify(ty: TypeRef,
cls: &[mut x86_64_reg_class], ix: uint,
off: uint) {
let t_align = ty_align(ty);
let t_size = ty_size(ty);
unsafe {
let t_align = ty_align(ty);
let t_size = ty_size(ty);
let misalign = off % t_align;
if misalign != 0u {
let mut i = off / 8u;
let e = (off + t_size + 7u) / 8u;
while i < e {
unify(cls, ix + i, memory_class);
i += 1u;
}
return;
}
match llvm::LLVMGetTypeKind(ty) as int {
8 /* integer */ |
12 /* pointer */ => {
unify(cls, ix + off / 8u, integer_class);
}
2 /* float */ => {
if off % 8u == 4u {
unify(cls, ix + off / 8u, sse_fv_class);
} else {
unify(cls, ix + off / 8u, sse_fs_class);
}
}
3 /* double */ => {
unify(cls, ix + off / 8u, sse_ds_class);
}
10 /* struct */ => {
classify_struct(struct_tys(ty), cls, ix, off);
}
11 /* array */ => {
let elt = llvm::LLVMGetElementType(ty);
let eltsz = ty_size(elt);
let len = llvm::LLVMGetArrayLength(ty) as uint;
let mut i = 0u;
while i < len {
classify(elt, cls, ix, off + i * eltsz);
let misalign = off % t_align;
if misalign != 0u {
let mut i = off / 8u;
let e = (off + t_size + 7u) / 8u;
while i < e {
unify(cls, ix + i, memory_class);
i += 1u;
}
return;
}
match llvm::LLVMGetTypeKind(ty) as int {
8 /* integer */ |
12 /* pointer */ => {
unify(cls, ix + off / 8u, integer_class);
}
2 /* float */ => {
if off % 8u == 4u {
unify(cls, ix + off / 8u, sse_fv_class);
} else {
unify(cls, ix + off / 8u, sse_fs_class);
}
}
3 /* double */ => {
unify(cls, ix + off / 8u, sse_ds_class);
}
10 /* struct */ => {
classify_struct(struct_tys(ty), cls, ix, off);
}
11 /* array */ => {
let elt = llvm::LLVMGetElementType(ty);
let eltsz = ty_size(elt);
let len = llvm::LLVMGetArrayLength(ty) as uint;
let mut i = 0u;
while i < len {
classify(elt, cls, ix, off + i * eltsz);
i += 1u;
}
}
_ => fail ~"classify: unhandled type"
}
_ => fail ~"classify: unhandled type"
}
}
fn fixup(ty: TypeRef, cls: &[mut x86_64_reg_class]) {
let mut i = 0u;
let llty = llvm::LLVMGetTypeKind(ty) as int;
let e = vec::len(cls);
if vec::len(cls) > 2u &&
(llty == 10 /* struct */ ||
llty == 11 /* array */) {
if is_sse(cls[i]) {
i += 1u;
unsafe {
let mut i = 0u;
let llty = llvm::LLVMGetTypeKind(ty) as int;
let e = vec::len(cls);
if vec::len(cls) > 2u &&
(llty == 10 /* struct */ ||
llty == 11 /* array */) {
if is_sse(cls[i]) {
i += 1u;
while i < e {
if cls[i] != sseup_class {
all_mem(cls);
return;
}
i += 1u;
}
} else {
all_mem(cls);
return
}
} else {
while i < e {
if cls[i] != sseup_class {
if cls[i] == memory_class {
all_mem(cls);
return;
}
i += 1u;
}
} else {
all_mem(cls);
return
}
} else {
while i < e {
if cls[i] == memory_class {
all_mem(cls);
return;
}
if cls[i] == x87up_class {
// for darwin
// cls[i] = sse_ds_class;
all_mem(cls);
return;
}
if cls[i] == sseup_class {
cls[i] = sse_int_class;
} else if is_sse(cls[i]) {
i += 1;
while cls[i] == sseup_class { i += 1u; }
} else if cls[i] == x87_class {
i += 1;
while cls[i] == x87up_class { i += 1u; }
} else {
i += 1;
if cls[i] == x87up_class {
// for darwin
// cls[i] = sse_ds_class;
all_mem(cls);
return;
}
if cls[i] == sseup_class {
cls[i] = sse_int_class;
} else if is_sse(cls[i]) {
i += 1;
while cls[i] == sseup_class { i += 1u; }
} else if cls[i] == x87_class {
i += 1;
while cls[i] == x87up_class { i += 1u; }
} else {
i += 1;
}
}
}
}
@@ -309,33 +319,35 @@ fn llvec_len(cls: &[x86_64_reg_class]) -> uint {
return len;
}
let mut tys = ~[];
let mut i = 0u;
let e = vec::len(cls);
while i < e {
match cls[i] {
integer_class => {
tys.push(T_i64());
unsafe {
let mut tys = ~[];
let mut i = 0u;
let e = vec::len(cls);
while i < e {
match cls[i] {
integer_class => {
tys.push(T_i64());
}
sse_fv_class => {
let vec_len = llvec_len(vec::tailn(cls, i + 1u)) * 2u;
let vec_ty = llvm::LLVMVectorType(T_f32(),
vec_len as c_uint);
tys.push(vec_ty);
i += vec_len;
loop;
}
sse_fs_class => {
tys.push(T_f32());
}
sse_ds_class => {
tys.push(T_f64());
}
_ => fail ~"llregtype: unhandled class"
}
sse_fv_class => {
let vec_len = llvec_len(vec::tailn(cls, i + 1u)) * 2u;
let vec_ty = llvm::LLVMVectorType(T_f32(),
vec_len as c_uint);
tys.push(vec_ty);
i += vec_len;
loop;
}
sse_fs_class => {
tys.push(T_f32());
}
sse_ds_class => {
tys.push(T_f64());
}
_ => fail ~"llregtype: unhandled class"
i += 1u;
}
i += 1u;
return T_struct(tys);
}
return T_struct(tys);
}
type x86_64_llty = {
@@ -354,13 +366,15 @@ fn x86_64_tys(atys: &[TypeRef],
rty: TypeRef,
ret_def: bool) -> x86_64_tys {
fn is_reg_ty(ty: TypeRef) -> bool {
return match llvm::LLVMGetTypeKind(ty) as int {
8 /* integer */ |
12 /* pointer */ |
2 /* float */ |
3 /* double */ => true,
_ => false
};
unsafe {
return match llvm::LLVMGetTypeKind(ty) as int {
8 /* integer */ |
12 /* pointer */ |
2 /* float */ |
3 /* double */ => true,
_ => false
};
}
}
fn is_pass_byval(cls: &[x86_64_reg_class]) -> bool {
@@ -431,8 +445,10 @@ fn decl_x86_64_fn(tys: x86_64_tys,
for vec::eachi(tys.attrs) |i, a| {
match *a {
option::Some(attr) => {
let llarg = get_param(llfn, i);
llvm::LLVMAddAttribute(llarg, attr as c_uint);
unsafe {
let llarg = get_param(llfn, i);
llvm::LLVMAddAttribute(llarg, attr as c_uint);
}
}
_ => ()
}
@@ -664,9 +680,11 @@ fn build_ret(bcx: block, tys: @c_stack_tys,
for vec::eachi((*x86_64).attrs) |i, a| {
match *a {
Some(attr) => {
llvm::LLVMAddInstrAttribute(
llretval, (i + 1u) as c_uint,
attr as c_uint);
unsafe {
llvm::LLVMAddInstrAttribute(
llretval, (i + 1u) as c_uint,
attr as c_uint);
}
}
_ => ()
}
+41 -26
View File
@@ -452,8 +452,10 @@ fn trans_struct_drop(bcx: block,
class_did, /*bad*/copy substs.tps);
// The second argument is the "self" argument for drop
let params = lib::llvm::fn_ty_param_tys(
llvm::LLVMGetElementType(llvm::LLVMTypeOf(dtor_addr)));
let params = unsafe {
lib::llvm::fn_ty_param_tys(
llvm::LLVMGetElementType(llvm::LLVMTypeOf(dtor_addr)))
};
// Class dtors have no explicit args, so the params should
// just consist of the output pointer and the environment
@@ -662,7 +664,9 @@ fn declare_tydesc(ccx: @crate_ctxt, t: ty::t) -> @tydesc_info {
note_unique_llvm_symbol(ccx, copy name);
log(debug, fmt!("+++ declare_tydesc %s %s", ty_to_str(ccx.tcx, t), name));
let gvar = str::as_c_str(name, |buf| {
llvm::LLVMAddGlobal(ccx.llmod, ccx.tydesc_type, buf)
unsafe {
llvm::LLVMAddGlobal(ccx.llmod, ccx.tydesc_type, buf)
}
});
let inf =
@{ty: t,
@@ -715,7 +719,7 @@ fn make_generic_glue_inner(ccx: @crate_ctxt, t: ty::t,
let bcx = top_scope_block(fcx, None);
let lltop = bcx.llbb;
let llrawptr0 = llvm::LLVMGetParam(llfn, 3u as c_uint);
let llrawptr0 = unsafe { llvm::LLVMGetParam(llfn, 3u as c_uint) };
helper(bcx, llrawptr0, t);
finish_fn(fcx, lltop);
return llfn;
@@ -753,32 +757,40 @@ fn emit_tydescs(ccx: @crate_ctxt) {
match copy ti.take_glue {
None => { ccx.stats.n_null_glues += 1u; C_null(glue_fn_ty) }
Some(v) => {
ccx.stats.n_real_glues += 1u;
llvm::LLVMConstPointerCast(v, glue_fn_ty)
unsafe {
ccx.stats.n_real_glues += 1u;
llvm::LLVMConstPointerCast(v, glue_fn_ty)
}
}
};
let drop_glue =
match copy ti.drop_glue {
None => { ccx.stats.n_null_glues += 1u; C_null(glue_fn_ty) }
Some(v) => {
ccx.stats.n_real_glues += 1u;
llvm::LLVMConstPointerCast(v, glue_fn_ty)
unsafe {
ccx.stats.n_real_glues += 1u;
llvm::LLVMConstPointerCast(v, glue_fn_ty)
}
}
};
let free_glue =
match copy ti.free_glue {
None => { ccx.stats.n_null_glues += 1u; C_null(glue_fn_ty) }
Some(v) => {
ccx.stats.n_real_glues += 1u;
llvm::LLVMConstPointerCast(v, glue_fn_ty)
unsafe {
ccx.stats.n_real_glues += 1u;
llvm::LLVMConstPointerCast(v, glue_fn_ty)
}
}
};
let visit_glue =
match copy ti.visit_glue {
None => { ccx.stats.n_null_glues += 1u; C_null(glue_fn_ty) }
Some(v) => {
ccx.stats.n_real_glues += 1u;
llvm::LLVMConstPointerCast(v, glue_fn_ty)
unsafe {
ccx.stats.n_real_glues += 1u;
llvm::LLVMConstPointerCast(v, glue_fn_ty)
}
}
};
@@ -796,21 +808,24 @@ fn emit_tydescs(ccx: @crate_ctxt) {
shape, // shape
shape_tables]); // shape_tables
let gvar = ti.tydesc;
llvm::LLVMSetInitializer(gvar, tydesc);
llvm::LLVMSetGlobalConstant(gvar, True);
lib::llvm::SetLinkage(gvar, lib::llvm::InternalLinkage);
unsafe {
let gvar = ti.tydesc;
llvm::LLVMSetInitializer(gvar, tydesc);
llvm::LLVMSetGlobalConstant(gvar, True);
lib::llvm::SetLinkage(gvar, lib::llvm::InternalLinkage);
// Index tydesc by addrspace.
if ti.addrspace > gc_box_addrspace {
let llty = T_ptr(ccx.tydesc_type);
let addrspace_name = fmt!("_gc_addrspace_metadata_%u",
ti.addrspace as uint);
let addrspace_gvar = str::as_c_str(addrspace_name, |buf| {
llvm::LLVMAddGlobal(ccx.llmod, llty, buf)
});
lib::llvm::SetLinkage(addrspace_gvar, lib::llvm::InternalLinkage);
llvm::LLVMSetInitializer(addrspace_gvar, gvar);
// Index tydesc by addrspace.
if ti.addrspace > gc_box_addrspace {
let llty = T_ptr(ccx.tydesc_type);
let addrspace_name = fmt!("_gc_addrspace_metadata_%u",
ti.addrspace as uint);
let addrspace_gvar = str::as_c_str(addrspace_name, |buf| {
llvm::LLVMAddGlobal(ccx.llmod, llty, buf)
});
lib::llvm::SetLinkage(addrspace_gvar,
lib::llvm::InternalLinkage);
llvm::LLVMSetInitializer(addrspace_gvar, gvar);
}
}
};
}
+32 -15
View File
@@ -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.
+12 -10
View File
@@ -755,16 +755,18 @@ fn get_vtable(ccx: @crate_ctxt, +origin: typeck::vtable_origin) -> ValueRef {
}
fn make_vtable(ccx: @crate_ctxt, ptrs: ~[ValueRef]) -> ValueRef {
let _icx = ccx.insn_ctxt("impl::make_vtable");
let tbl = C_struct(ptrs);
let vt_gvar =
str::as_c_str(ccx.sess.str_of((ccx.names)(~"vtable")), |buf| {
llvm::LLVMAddGlobal(ccx.llmod, val_ty(tbl), buf)
});
llvm::LLVMSetInitializer(vt_gvar, tbl);
llvm::LLVMSetGlobalConstant(vt_gvar, lib::llvm::True);
lib::llvm::SetLinkage(vt_gvar, lib::llvm::InternalLinkage);
vt_gvar
unsafe {
let _icx = ccx.insn_ctxt("impl::make_vtable");
let tbl = C_struct(ptrs);
let vt_gvar =
str::as_c_str(ccx.sess.str_of((ccx.names)(~"vtable")), |buf| {
llvm::LLVMAddGlobal(ccx.llmod, val_ty(tbl), buf)
});
llvm::LLVMSetInitializer(vt_gvar, tbl);
llvm::LLVMSetGlobalConstant(vt_gvar, lib::llvm::True);
lib::llvm::SetLinkage(vt_gvar, lib::llvm::InternalLinkage);
vt_gvar
}
}
fn make_impl_vtable(ccx: @crate_ctxt, impl_id: ast::def_id, substs: ~[ty::t],
+19 -14
View File
@@ -38,26 +38,31 @@
fn mk_global(ccx: @crate_ctxt, name: ~str, llval: ValueRef, internal: bool) ->
ValueRef {
let llglobal = do str::as_c_str(name) |buf| {
llvm::LLVMAddGlobal(ccx.llmod, val_ty(llval), buf)
};
llvm::LLVMSetInitializer(llglobal, llval);
llvm::LLVMSetGlobalConstant(llglobal, True);
unsafe {
let llglobal = do str::as_c_str(name) |buf| {
llvm::LLVMAddGlobal(ccx.llmod, val_ty(llval), buf)
};
llvm::LLVMSetInitializer(llglobal, llval);
llvm::LLVMSetGlobalConstant(llglobal, True);
if internal {
::lib::llvm::SetLinkage(llglobal, ::lib::llvm::InternalLinkage);
if internal {
::lib::llvm::SetLinkage(llglobal,
::lib::llvm::InternalLinkage);
}
return llglobal;
}
return llglobal;
}
fn mk_ctxt(llmod: ModuleRef) -> ctxt {
let llshapetablesty = trans::common::T_named_struct(~"shapes");
let _llshapetables = str::as_c_str(~"shapes", |buf| {
llvm::LLVMAddGlobal(llmod, llshapetablesty, buf)
});
unsafe {
let llshapetablesty = trans::common::T_named_struct(~"shapes");
let _llshapetables = str::as_c_str(~"shapes", |buf| {
llvm::LLVMAddGlobal(llmod, llshapetablesty, buf)
});
return {mut next_tag_id: 0u16, pad: 0u16, pad2: 0u32};
return {mut next_tag_id: 0u16, pad: 0u16, pad2: 0u32};
}
}
/*
+14 -7
View File
@@ -256,13 +256,20 @@ fn trans_lit_str(bcx: block,
match dest {
Ignore => bcx,
SaveIn(lldest) => {
let bytes = lit_str.len() + 1; // count null-terminator too
let llbytes = C_uint(bcx.ccx(), bytes);
let llcstr = C_cstr(bcx.ccx(), /*bad*/copy *lit_str);
let llcstr = llvm::LLVMConstPointerCast(llcstr, T_ptr(T_i8()));
Store(bcx, llcstr, GEPi(bcx, lldest, [0u, abi::slice_elt_base]));
Store(bcx, llbytes, GEPi(bcx, lldest, [0u, abi::slice_elt_len]));
bcx
unsafe {
let bytes = lit_str.len() + 1; // count null-terminator too
let llbytes = C_uint(bcx.ccx(), bytes);
let llcstr = C_cstr(bcx.ccx(), /*bad*/copy *lit_str);
let llcstr = llvm::LLVMConstPointerCast(llcstr,
T_ptr(T_i8()));
Store(bcx,
llcstr,
GEPi(bcx, lldest, [0u, abi::slice_elt_base]));
Store(bcx,
llbytes,
GEPi(bcx, lldest, [0u, abi::slice_elt_len]));
bcx
}
}
}
}
+15 -11
View File
@@ -50,17 +50,19 @@ fn type_of_explicit_args(ccx: @crate_ctxt, inputs: ~[ty::arg]) -> ~[TypeRef] {
fn type_of_fn(cx: @crate_ctxt, inputs: ~[ty::arg],
output: ty::t) -> TypeRef {
let mut atys: ~[TypeRef] = ~[];
unsafe {
let mut atys: ~[TypeRef] = ~[];
// Arg 0: Output pointer.
atys.push(T_ptr(type_of(cx, output)));
// Arg 0: Output pointer.
atys.push(T_ptr(type_of(cx, output)));
// Arg 1: Environment
atys.push(T_opaque_box_ptr(cx));
// Arg 1: Environment
atys.push(T_opaque_box_ptr(cx));
// ... then explicit args.
atys.push_all(type_of_explicit_args(cx, inputs));
return T_fn(atys, llvm::LLVMVoidType());
// ... then explicit args.
atys.push_all(type_of_explicit_args(cx, inputs));
return T_fn(atys, llvm::LLVMVoidType());
}
}
// Given a function type and a count of ty params, construct an llvm type
@@ -279,9 +281,11 @@ fn llvm_type_name(cx: @crate_ctxt,
}
fn type_of_dtor(ccx: @crate_ctxt, self_ty: ty::t) -> TypeRef {
T_fn(~[T_ptr(type_of(ccx, ty::mk_nil(ccx.tcx))), // output pointer
T_ptr(type_of(ccx, self_ty))], // self arg
llvm::LLVMVoidType())
unsafe {
T_fn(~[T_ptr(type_of(ccx, ty::mk_nil(ccx.tcx))), // output pointer
T_ptr(type_of(ccx, self_ty))], // self arg
llvm::LLVMVoidType())
}
}
fn type_of_rooted(ccx: @crate_ctxt, t: ty::t) -> TypeRef {
+13 -11
View File
@@ -151,17 +151,19 @@ fn pandoc_writer(
fn readclose(fd: libc::c_int) -> ~str {
// Copied from run::program_output
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)
}
}
fn generic_writer(+process: fn~(+markdown: ~str)) -> Writer {
+3 -1
View File
@@ -57,7 +57,9 @@
extern mod rustrt {
#[rust_stack]
fn rust_call_tydesc_glue(root: *u8, tydesc: *TypeDesc, field: size_t);
unsafe fn rust_call_tydesc_glue(root: *u8,
tydesc: *TypeDesc,
field: size_t);
}
// This probably belongs somewhere else. Needs to be kept in sync with
// changes to glue...
+29 -13
View File
@@ -18,33 +18,47 @@
#[abi = "cdecl"]
extern mod rustrt {
#[legacy_exports];
fn debug_tydesc(td: *sys::TypeDesc);
fn debug_opaque(td: *sys::TypeDesc, x: *());
fn debug_box(td: *sys::TypeDesc, x: *());
fn debug_tag(td: *sys::TypeDesc, x: *());
fn debug_fn(td: *sys::TypeDesc, x: *());
fn debug_ptrcast(td: *sys::TypeDesc, x: *()) -> *();
fn rust_dbg_breakpoint();
unsafe fn debug_tydesc(td: *sys::TypeDesc);
unsafe fn debug_opaque(td: *sys::TypeDesc, x: *());
unsafe fn debug_box(td: *sys::TypeDesc, x: *());
unsafe fn debug_tag(td: *sys::TypeDesc, x: *());
unsafe fn debug_fn(td: *sys::TypeDesc, x: *());
unsafe fn debug_ptrcast(td: *sys::TypeDesc, x: *()) -> *();
unsafe fn rust_dbg_breakpoint();
}
pub fn debug_tydesc<T>() {
rustrt::debug_tydesc(sys::get_type_desc::<T>());
unsafe {
rustrt::debug_tydesc(sys::get_type_desc::<T>());
}
}
pub fn debug_opaque<T>(x: T) {
rustrt::debug_opaque(sys::get_type_desc::<T>(), ptr::addr_of(&x) as *());
unsafe {
rustrt::debug_opaque(sys::get_type_desc::<T>(),
ptr::addr_of(&x) as *());
}
}
pub fn debug_box<T>(x: @T) {
rustrt::debug_box(sys::get_type_desc::<T>(), ptr::addr_of(&x) as *());
unsafe {
rustrt::debug_box(sys::get_type_desc::<T>(),
ptr::addr_of(&x) as *());
}
}
pub fn debug_tag<T>(x: T) {
rustrt::debug_tag(sys::get_type_desc::<T>(), ptr::addr_of(&x) as *());
unsafe {
rustrt::debug_tag(sys::get_type_desc::<T>(),
ptr::addr_of(&x) as *());
}
}
pub fn debug_fn<T>(x: T) {
rustrt::debug_fn(sys::get_type_desc::<T>(), ptr::addr_of(&x) as *());
unsafe {
rustrt::debug_fn(sys::get_type_desc::<T>(),
ptr::addr_of(&x) as *());
}
}
pub unsafe fn ptr_cast<T, U>(x: @T) -> @U {
@@ -55,7 +69,9 @@ pub unsafe fn ptr_cast<T, U>(x: @T) -> @U {
/// Triggers a debugger breakpoint
pub fn breakpoint() {
rustrt::rust_dbg_breakpoint();
unsafe {
rustrt::rust_dbg_breakpoint();
}
}
#[test]
+4 -3
View File
@@ -33,9 +33,10 @@
#[nolink]
extern mod rustrt {
fn rust_uv_current_kernel_malloc(size: libc::c_uint) -> *libc::c_void;
fn rust_uv_current_kernel_free(mem: *libc::c_void);
fn rust_uv_helper_uv_tcp_t_size() -> libc::c_uint;
unsafe fn rust_uv_current_kernel_malloc(size: libc::c_uint)
-> *libc::c_void;
unsafe fn rust_uv_current_kernel_free(mem: *libc::c_void);
unsafe fn rust_uv_helper_uv_tcp_t_size() -> libc::c_uint;
}
/**
+7 -7
View File
@@ -18,13 +18,13 @@
extern mod rustrt {
#[legacy_exports];
fn linenoise(prompt: *c_char) -> *c_char;
fn linenoiseHistoryAdd(line: *c_char) -> c_int;
fn linenoiseHistorySetMaxLen(len: c_int) -> c_int;
fn linenoiseHistorySave(file: *c_char) -> c_int;
fn linenoiseHistoryLoad(file: *c_char) -> c_int;
fn linenoiseSetCompletionCallback(callback: *u8);
fn linenoiseAddCompletion(completions: *(), line: *c_char);
unsafe fn linenoise(prompt: *c_char) -> *c_char;
unsafe fn linenoiseHistoryAdd(line: *c_char) -> c_int;
unsafe fn linenoiseHistorySetMaxLen(len: c_int) -> c_int;
unsafe fn linenoiseHistorySave(file: *c_char) -> c_int;
unsafe fn linenoiseHistoryLoad(file: *c_char) -> c_int;
unsafe fn linenoiseSetCompletionCallback(callback: *u8);
unsafe fn linenoiseAddCompletion(completions: *(), line: *c_char);
}
/// Add a line to history
+6 -4
View File
@@ -39,7 +39,7 @@
#[abi = "cdecl"]
extern mod rustrt {
#[legacy_exports];
fn rust_sched_threads() -> size_t;
unsafe fn rust_sched_threads() -> size_t;
}
// The name of a test. By convention this follows the rules for rust
@@ -335,9 +335,11 @@ fn run_tests(opts: &TestOpts,
const sched_overcommit : uint = 4u;
fn get_concurrency() -> uint {
let threads = rustrt::rust_sched_threads() as uint;
if threads == 1u { 1u }
else { threads * sched_overcommit }
unsafe {
let threads = rustrt::rust_sched_threads() as uint;
if threads == 1u { 1u }
else { threads * sched_overcommit }
}
}
#[allow(non_implicitly_copyable_typarams)]
+41 -29
View File
@@ -23,16 +23,16 @@
#[abi = "cdecl"]
extern mod rustrt {
#[legacy_exports]
fn get_time(sec: &mut i64, nsec: &mut i32);
unsafe fn get_time(sec: &mut i64, nsec: &mut i32);
fn precise_time_ns(ns: &mut u64);
unsafe fn precise_time_ns(ns: &mut u64);
fn rust_tzset();
unsafe fn rust_tzset();
// FIXME: The i64 values can be passed by-val when #2064 is fixed.
fn rust_gmtime(&&sec: i64, &&nsec: i32, &&result: Tm);
fn rust_localtime(&&sec: i64, &&nsec: i32, &&result: Tm);
fn rust_timegm(&&tm: Tm, sec: &mut i64);
fn rust_mktime(&&tm: Tm, sec: &mut i64);
unsafe fn rust_gmtime(&&sec: i64, &&nsec: i32, &&result: Tm);
unsafe fn rust_localtime(&&sec: i64, &&nsec: i32, &&result: Tm);
unsafe fn rust_timegm(&&tm: Tm, sec: &mut i64);
unsafe fn rust_mktime(&&tm: Tm, sec: &mut i64);
}
/// A record specifying a time value in seconds and nanoseconds.
@@ -58,10 +58,12 @@ impl Timespec : Eq {
* nanoseconds since 1970-01-01T00:00:00Z.
*/
pub fn get_time() -> Timespec {
let mut sec = 0i64;
let mut nsec = 0i32;
rustrt::get_time(&mut sec, &mut nsec);
return Timespec::new(sec, nsec);
unsafe {
let mut sec = 0i64;
let mut nsec = 0i32;
rustrt::get_time(&mut sec, &mut nsec);
return Timespec::new(sec, nsec);
}
}
@@ -70,9 +72,11 @@ pub fn get_time() -> Timespec {
* in nanoseconds since an unspecified epoch.
*/
pub fn precise_time_ns() -> u64 {
let mut ns = 0u64;
rustrt::precise_time_ns(&mut ns);
ns
unsafe {
let mut ns = 0u64;
rustrt::precise_time_ns(&mut ns);
ns
}
}
@@ -85,7 +89,9 @@ pub fn precise_time_s() -> float {
}
pub fn tzset() {
rustrt::rust_tzset();
unsafe {
rustrt::rust_tzset();
}
}
#[auto_encode]
@@ -142,10 +148,12 @@ impl Tm : Eq {
/// Returns the specified time in UTC
pub fn at_utc(clock: Timespec) -> Tm {
let mut Timespec { sec, nsec } = clock;
let mut tm = empty_tm();
rustrt::rust_gmtime(sec, nsec, tm);
move tm
unsafe {
let mut Timespec { sec, nsec } = clock;
let mut tm = empty_tm();
rustrt::rust_gmtime(sec, nsec, tm);
move tm
}
}
/// Returns the current time in UTC
@@ -155,10 +163,12 @@ pub fn now_utc() -> Tm {
/// Returns the specified time in the local timezone
pub fn at(clock: Timespec) -> Tm {
let mut Timespec { sec, nsec } = clock;
let mut tm = empty_tm();
rustrt::rust_localtime(sec, nsec, tm);
move tm
unsafe {
let mut Timespec { sec, nsec } = clock;
let mut tm = empty_tm();
rustrt::rust_localtime(sec, nsec, tm);
move tm
}
}
/// Returns the current time in the local timezone
@@ -183,13 +193,15 @@ pub fn now() -> Tm {
impl Tm {
/// Convert time to the seconds from January 1, 1970
fn to_timespec() -> Timespec {
let mut sec = 0i64;
if self.tm_gmtoff == 0_i32 {
rustrt::rust_timegm(self, &mut sec);
} else {
rustrt::rust_mktime(self, &mut sec);
unsafe {
let mut sec = 0i64;
if self.tm_gmtoff == 0_i32 {
rustrt::rust_timegm(self, &mut sec);
} else {
rustrt::rust_mktime(self, &mut sec);
}
Timespec::new(sec, self.tm_nsec)
}
Timespec::new(sec, self.tm_nsec)
}
/// Convert time to the local timezone
+7 -7
View File
@@ -160,13 +160,13 @@ pub mod icu {
#[link_name = "icuuc"]
#[abi = "cdecl"]
pub extern mod libicu {
pure fn u_hasBinaryProperty(c: UChar32, which: UProperty) -> UBool;
pure fn u_isdigit(c: UChar32) -> UBool;
pure fn u_islower(c: UChar32) -> UBool;
pure fn u_isspace(c: UChar32) -> UBool;
pure fn u_isupper(c: UChar32) -> UBool;
pure fn u_tolower(c: UChar32) -> UChar32;
pure fn u_toupper(c: UChar32) -> UChar32;
unsafe fn u_hasBinaryProperty(c: UChar32, which: UProperty) -> UBool;
unsafe fn u_isdigit(c: UChar32) -> UBool;
unsafe fn u_islower(c: UChar32) -> UBool;
unsafe fn u_isspace(c: UChar32) -> UBool;
unsafe fn u_isupper(c: UChar32) -> UBool;
unsafe fn u_tolower(c: UChar32) -> UChar32;
unsafe fn u_toupper(c: UChar32) -> UChar32;
}
}
+1 -1
View File
@@ -27,7 +27,7 @@
use core::vec;
extern mod rustrt {
fn rust_uv_get_kernel_global_chan_ptr() -> *libc::uintptr_t;
unsafe fn rust_uv_get_kernel_global_chan_ptr() -> *libc::uintptr_t;
}
/**
+108 -93
View File
@@ -581,127 +581,142 @@ pub fn gen_stub_uv_getaddrinfo_t() -> uv_getaddrinfo_t {
#[nolink]
extern mod rustrt {
// libuv public API
fn rust_uv_loop_new() -> *libc::c_void;
fn rust_uv_loop_delete(lp: *libc::c_void);
fn rust_uv_loop_refcount(loop_ptr: *libc::c_void) -> libc::c_int;
fn rust_uv_run(loop_handle: *libc::c_void);
fn rust_uv_close(handle: *libc::c_void, cb: *u8);
fn rust_uv_async_send(handle: *uv_async_t);
fn rust_uv_async_init(loop_handle: *libc::c_void,
unsafe fn rust_uv_loop_new() -> *libc::c_void;
unsafe fn rust_uv_loop_delete(lp: *libc::c_void);
unsafe fn rust_uv_loop_refcount(loop_ptr: *libc::c_void) -> libc::c_int;
unsafe fn rust_uv_run(loop_handle: *libc::c_void);
unsafe fn rust_uv_close(handle: *libc::c_void, cb: *u8);
unsafe fn rust_uv_async_send(handle: *uv_async_t);
unsafe fn rust_uv_async_init(loop_handle: *libc::c_void,
async_handle: *uv_async_t,
cb: *u8) -> libc::c_int;
fn rust_uv_tcp_init(
unsafe fn rust_uv_tcp_init(
loop_handle: *libc::c_void,
handle_ptr: *uv_tcp_t) -> libc::c_int;
// FIXME ref #2604 .. ?
fn rust_uv_buf_init(out_buf: *uv_buf_t, base: *u8,
unsafe fn rust_uv_buf_init(out_buf: *uv_buf_t, base: *u8,
len: libc::size_t);
fn rust_uv_last_error(loop_handle: *libc::c_void) -> uv_err_t;
unsafe fn rust_uv_last_error(loop_handle: *libc::c_void) -> uv_err_t;
// FIXME ref #2064
fn rust_uv_strerror(err: *uv_err_t) -> *libc::c_char;
unsafe fn rust_uv_strerror(err: *uv_err_t) -> *libc::c_char;
// FIXME ref #2064
fn rust_uv_err_name(err: *uv_err_t) -> *libc::c_char;
fn rust_uv_ip4_addr(ip: *u8, port: libc::c_int)
unsafe fn rust_uv_err_name(err: *uv_err_t) -> *libc::c_char;
unsafe fn rust_uv_ip4_addr(ip: *u8, port: libc::c_int)
-> sockaddr_in;
fn rust_uv_ip6_addr(ip: *u8, port: libc::c_int)
unsafe fn rust_uv_ip6_addr(ip: *u8, port: libc::c_int)
-> sockaddr_in6;
fn rust_uv_ip4_name(src: *sockaddr_in, dst: *u8, size: libc::size_t)
-> libc::c_int;
fn rust_uv_ip6_name(src: *sockaddr_in6, dst: *u8, size: libc::size_t)
-> libc::c_int;
fn rust_uv_ip4_port(src: *sockaddr_in) -> libc::c_uint;
fn rust_uv_ip6_port(src: *sockaddr_in6) -> libc::c_uint;
unsafe fn rust_uv_ip4_name(src: *sockaddr_in,
dst: *u8,
size: libc::size_t)
-> libc::c_int;
unsafe fn rust_uv_ip6_name(src: *sockaddr_in6,
dst: *u8,
size: libc::size_t)
-> libc::c_int;
unsafe fn rust_uv_ip4_port(src: *sockaddr_in) -> libc::c_uint;
unsafe fn rust_uv_ip6_port(src: *sockaddr_in6) -> libc::c_uint;
// FIXME ref #2064
fn rust_uv_tcp_connect(connect_ptr: *uv_connect_t,
tcp_handle_ptr: *uv_tcp_t,
++after_cb: *u8,
++addr: *sockaddr_in) -> libc::c_int;
unsafe fn rust_uv_tcp_connect(connect_ptr: *uv_connect_t,
tcp_handle_ptr: *uv_tcp_t,
++after_cb: *u8,
++addr: *sockaddr_in) -> libc::c_int;
// FIXME ref #2064
fn rust_uv_tcp_bind(tcp_server: *uv_tcp_t,
++addr: *sockaddr_in) -> libc::c_int;
unsafe fn rust_uv_tcp_bind(tcp_server: *uv_tcp_t,
++addr: *sockaddr_in) -> libc::c_int;
// FIXME ref #2064
fn rust_uv_tcp_connect6(connect_ptr: *uv_connect_t,
tcp_handle_ptr: *uv_tcp_t,
++after_cb: *u8,
++addr: *sockaddr_in6) -> libc::c_int;
unsafe fn rust_uv_tcp_connect6(connect_ptr: *uv_connect_t,
tcp_handle_ptr: *uv_tcp_t,
++after_cb: *u8,
++addr: *sockaddr_in6) -> libc::c_int;
// FIXME ref #2064
fn rust_uv_tcp_bind6(tcp_server: *uv_tcp_t,
++addr: *sockaddr_in6) -> libc::c_int;
fn rust_uv_tcp_getpeername(tcp_handle_ptr: *uv_tcp_t,
++name: *sockaddr_in) -> libc::c_int;
fn rust_uv_tcp_getpeername6(tcp_handle_ptr: *uv_tcp_t,
++name: *sockaddr_in6) ->libc::c_int;
fn rust_uv_listen(stream: *libc::c_void, backlog: libc::c_int,
cb: *u8) -> libc::c_int;
fn rust_uv_accept(server: *libc::c_void, client: *libc::c_void)
-> libc::c_int;
fn rust_uv_write(req: *libc::c_void, stream: *libc::c_void,
++buf_in: *uv_buf_t, buf_cnt: libc::c_int,
cb: *u8) -> libc::c_int;
fn rust_uv_read_start(stream: *libc::c_void, on_alloc: *u8,
on_read: *u8) -> libc::c_int;
fn rust_uv_read_stop(stream: *libc::c_void) -> libc::c_int;
fn rust_uv_timer_init(loop_handle: *libc::c_void,
timer_handle: *uv_timer_t) -> libc::c_int;
fn rust_uv_timer_start(
unsafe fn rust_uv_tcp_bind6(tcp_server: *uv_tcp_t,
++addr: *sockaddr_in6) -> libc::c_int;
unsafe fn rust_uv_tcp_getpeername(tcp_handle_ptr: *uv_tcp_t,
++name: *sockaddr_in) -> libc::c_int;
unsafe fn rust_uv_tcp_getpeername6(tcp_handle_ptr: *uv_tcp_t,
++name: *sockaddr_in6) ->libc::c_int;
unsafe fn rust_uv_listen(stream: *libc::c_void,
backlog: libc::c_int,
cb: *u8) -> libc::c_int;
unsafe fn rust_uv_accept(server: *libc::c_void, client: *libc::c_void)
-> libc::c_int;
unsafe fn rust_uv_write(req: *libc::c_void,
stream: *libc::c_void,
++buf_in: *uv_buf_t,
buf_cnt: libc::c_int,
cb: *u8)
-> libc::c_int;
unsafe fn rust_uv_read_start(stream: *libc::c_void,
on_alloc: *u8,
on_read: *u8)
-> libc::c_int;
unsafe fn rust_uv_read_stop(stream: *libc::c_void) -> libc::c_int;
unsafe fn rust_uv_timer_init(loop_handle: *libc::c_void,
timer_handle: *uv_timer_t)
-> libc::c_int;
unsafe fn rust_uv_timer_start(
timer_handle: *uv_timer_t,
cb: *u8,
timeout: libc::c_uint,
repeat: libc::c_uint) -> libc::c_int;
fn rust_uv_timer_stop(handle: *uv_timer_t) -> libc::c_int;
unsafe fn rust_uv_timer_stop(handle: *uv_timer_t) -> libc::c_int;
fn rust_uv_getaddrinfo(loop_ptr: *libc::c_void,
handle: *uv_getaddrinfo_t,
cb: *u8,
node_name_ptr: *u8,
service_name_ptr: *u8,
// should probably only pass ptr::null()
hints: *addrinfo) -> libc::c_int;
fn rust_uv_freeaddrinfo(res: *addrinfo);
unsafe fn rust_uv_getaddrinfo(loop_ptr: *libc::c_void,
handle: *uv_getaddrinfo_t,
cb: *u8,
node_name_ptr: *u8,
service_name_ptr: *u8,
// should probably only pass ptr::null()
hints: *addrinfo)
-> libc::c_int;
unsafe fn rust_uv_freeaddrinfo(res: *addrinfo);
// data accessors/helpers for rust-mapped uv structs
fn rust_uv_helper_get_INADDR_NONE() -> u32;
fn rust_uv_is_ipv4_addrinfo(input: *addrinfo) -> bool;
fn rust_uv_is_ipv6_addrinfo(input: *addrinfo) -> bool;
fn rust_uv_get_next_addrinfo(input: *addrinfo) -> *addrinfo;
fn rust_uv_addrinfo_as_sockaddr_in(input: *addrinfo) -> *sockaddr_in;
fn rust_uv_addrinfo_as_sockaddr_in6(input: *addrinfo) -> *sockaddr_in6;
fn rust_uv_malloc_buf_base_of(sug_size: libc::size_t) -> *u8;
fn rust_uv_free_base_of_buf(++buf: uv_buf_t);
fn rust_uv_get_stream_handle_from_connect_req(
unsafe fn rust_uv_helper_get_INADDR_NONE() -> u32;
unsafe fn rust_uv_is_ipv4_addrinfo(input: *addrinfo) -> bool;
unsafe fn rust_uv_is_ipv6_addrinfo(input: *addrinfo) -> bool;
unsafe fn rust_uv_get_next_addrinfo(input: *addrinfo) -> *addrinfo;
unsafe fn rust_uv_addrinfo_as_sockaddr_in(input: *addrinfo)
-> *sockaddr_in;
unsafe fn rust_uv_addrinfo_as_sockaddr_in6(input: *addrinfo)
-> *sockaddr_in6;
unsafe fn rust_uv_malloc_buf_base_of(sug_size: libc::size_t) -> *u8;
unsafe fn rust_uv_free_base_of_buf(++buf: uv_buf_t);
unsafe fn rust_uv_get_stream_handle_from_connect_req(
connect_req: *uv_connect_t)
-> *uv_stream_t;
fn rust_uv_get_stream_handle_from_write_req(
unsafe fn rust_uv_get_stream_handle_from_write_req(
write_req: *uv_write_t)
-> *uv_stream_t;
fn rust_uv_get_loop_for_uv_handle(handle: *libc::c_void)
unsafe fn rust_uv_get_loop_for_uv_handle(handle: *libc::c_void)
-> *libc::c_void;
fn rust_uv_get_data_for_uv_loop(loop_ptr: *libc::c_void) -> *libc::c_void;
fn rust_uv_set_data_for_uv_loop(loop_ptr: *libc::c_void,
data: *libc::c_void);
fn rust_uv_get_data_for_uv_handle(handle: *libc::c_void)
-> *libc::c_void;
fn rust_uv_set_data_for_uv_handle(handle: *libc::c_void,
data: *libc::c_void);
fn rust_uv_get_data_for_req(req: *libc::c_void) -> *libc::c_void;
fn rust_uv_set_data_for_req(req: *libc::c_void,
data: *libc::c_void);
fn rust_uv_get_base_from_buf(++buf: uv_buf_t) -> *u8;
fn rust_uv_get_len_from_buf(++buf: uv_buf_t) -> libc::size_t;
unsafe fn rust_uv_get_data_for_uv_loop(loop_ptr: *libc::c_void)
-> *libc::c_void;
unsafe fn rust_uv_set_data_for_uv_loop(loop_ptr: *libc::c_void,
data: *libc::c_void);
unsafe fn rust_uv_get_data_for_uv_handle(handle: *libc::c_void)
-> *libc::c_void;
unsafe fn rust_uv_set_data_for_uv_handle(handle: *libc::c_void,
data: *libc::c_void);
unsafe fn rust_uv_get_data_for_req(req: *libc::c_void) -> *libc::c_void;
unsafe fn rust_uv_set_data_for_req(req: *libc::c_void,
data: *libc::c_void);
unsafe fn rust_uv_get_base_from_buf(++buf: uv_buf_t) -> *u8;
unsafe fn rust_uv_get_len_from_buf(++buf: uv_buf_t) -> libc::size_t;
// sizeof testing helpers
fn rust_uv_helper_uv_tcp_t_size() -> libc::c_uint;
fn rust_uv_helper_uv_connect_t_size() -> libc::c_uint;
fn rust_uv_helper_uv_buf_t_size() -> libc::c_uint;
fn rust_uv_helper_uv_write_t_size() -> libc::c_uint;
fn rust_uv_helper_uv_err_t_size() -> libc::c_uint;
fn rust_uv_helper_sockaddr_in_size() -> libc::c_uint;
fn rust_uv_helper_sockaddr_in6_size() -> libc::c_uint;
fn rust_uv_helper_uv_async_t_size() -> libc::c_uint;
fn rust_uv_helper_uv_timer_t_size() -> libc::c_uint;
fn rust_uv_helper_uv_getaddrinfo_t_size() -> libc::c_uint;
fn rust_uv_helper_addrinfo_size() -> libc::c_uint;
fn rust_uv_helper_addr_in_size() -> libc::c_uint;
unsafe fn rust_uv_helper_uv_tcp_t_size() -> libc::c_uint;
unsafe fn rust_uv_helper_uv_connect_t_size() -> libc::c_uint;
unsafe fn rust_uv_helper_uv_buf_t_size() -> libc::c_uint;
unsafe fn rust_uv_helper_uv_write_t_size() -> libc::c_uint;
unsafe fn rust_uv_helper_uv_err_t_size() -> libc::c_uint;
unsafe fn rust_uv_helper_sockaddr_in_size() -> libc::c_uint;
unsafe fn rust_uv_helper_sockaddr_in6_size() -> libc::c_uint;
unsafe fn rust_uv_helper_uv_async_t_size() -> libc::c_uint;
unsafe fn rust_uv_helper_uv_timer_t_size() -> libc::c_uint;
unsafe fn rust_uv_helper_uv_getaddrinfo_t_size() -> libc::c_uint;
unsafe fn rust_uv_helper_addrinfo_size() -> libc::c_uint;
unsafe fn rust_uv_helper_addr_in_size() -> libc::c_uint;
}
pub unsafe fn loop_new() -> *libc::c_void {