mirror of
https://github.com/rust-lang/rust.git
synced 2026-04-27 18:57:42 +03:00
librustc: Make all external functions unsafe. r=tjc
This commit is contained in:
@@ -118,14 +118,16 @@ fn writeclose(fd: c_int, s: Option<~str>) {
|
||||
}
|
||||
|
||||
fn readclose(fd: c_int) -> ~str {
|
||||
// Copied from run::program_output
|
||||
let file = os::fdopen(fd);
|
||||
let reader = io::FILE_reader(file, false);
|
||||
let mut buf = ~"";
|
||||
while !reader.eof() {
|
||||
let bytes = reader.read_bytes(4096u);
|
||||
str::push_str(&mut buf, str::from_bytes(bytes));
|
||||
unsafe {
|
||||
// Copied from run::program_output
|
||||
let file = os::fdopen(fd);
|
||||
let reader = io::FILE_reader(file, false);
|
||||
let mut buf = ~"";
|
||||
while !reader.eof() {
|
||||
let bytes = reader.read_bytes(4096u);
|
||||
str::push_str(&mut buf, str::from_bytes(bytes));
|
||||
}
|
||||
os::fclose(file);
|
||||
return buf;
|
||||
}
|
||||
os::fclose(file);
|
||||
return buf;
|
||||
}
|
||||
|
||||
@@ -30,9 +30,9 @@
|
||||
#[abi = "cdecl"]
|
||||
pub extern mod rustrt {
|
||||
#[legacy_exports];
|
||||
fn vec_reserve_shared_actual(++t: *sys::TypeDesc,
|
||||
++v: **vec::raw::VecRepr,
|
||||
++n: libc::size_t);
|
||||
unsafe fn vec_reserve_shared_actual(++t: *sys::TypeDesc,
|
||||
++v: **vec::raw::VecRepr,
|
||||
++n: libc::size_t);
|
||||
}
|
||||
|
||||
#[abi = "rust-intrinsic"]
|
||||
|
||||
@@ -160,6 +160,6 @@ pub unsafe fn annihilate() {
|
||||
extern mod rustrt {
|
||||
#[legacy_exports];
|
||||
#[rust_stack]
|
||||
/*priv*/ fn rust_get_task() -> *c_void;
|
||||
/*priv*/ unsafe fn rust_get_task() -> *c_void;
|
||||
}
|
||||
|
||||
|
||||
+95
-94
@@ -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
@@ -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
@@ -16,12 +16,95 @@
|
||||
|
||||
use cmath;
|
||||
use cmp;
|
||||
use libc::{c_double, c_int};
|
||||
use libc;
|
||||
use num;
|
||||
|
||||
pub use cmath::c_double_utils::*;
|
||||
pub use cmath::c_double_targ_consts::*;
|
||||
|
||||
macro_rules! delegate(
|
||||
(
|
||||
fn $name:ident(
|
||||
$(
|
||||
$arg:ident : $arg_ty:ty
|
||||
),*
|
||||
) -> $rv:ty = $bound_name:path
|
||||
) => (
|
||||
pub pure fn $name($( $arg : $arg_ty ),*) -> $rv {
|
||||
unsafe {
|
||||
$bound_name($( $arg ),*)
|
||||
}
|
||||
}
|
||||
)
|
||||
)
|
||||
|
||||
delegate!(fn acos(n: c_double) -> c_double = cmath::c_double_utils::acos)
|
||||
delegate!(fn asin(n: c_double) -> c_double = cmath::c_double_utils::asin)
|
||||
delegate!(fn atan(n: c_double) -> c_double = cmath::c_double_utils::atan)
|
||||
delegate!(fn atan2(a: c_double, b: c_double) -> c_double =
|
||||
cmath::c_double_utils::atan2)
|
||||
delegate!(fn cbrt(n: c_double) -> c_double = cmath::c_double_utils::cbrt)
|
||||
delegate!(fn ceil(n: c_double) -> c_double = cmath::c_double_utils::ceil)
|
||||
delegate!(fn copysign(x: c_double, y: c_double) -> c_double =
|
||||
cmath::c_double_utils::copysign)
|
||||
delegate!(fn cos(n: c_double) -> c_double = cmath::c_double_utils::cos)
|
||||
delegate!(fn cosh(n: c_double) -> c_double = cmath::c_double_utils::cosh)
|
||||
delegate!(fn erf(n: c_double) -> c_double = cmath::c_double_utils::erf)
|
||||
delegate!(fn erfc(n: c_double) -> c_double = cmath::c_double_utils::erfc)
|
||||
delegate!(fn exp(n: c_double) -> c_double = cmath::c_double_utils::exp)
|
||||
delegate!(fn expm1(n: c_double) -> c_double = cmath::c_double_utils::expm1)
|
||||
delegate!(fn exp2(n: c_double) -> c_double = cmath::c_double_utils::exp2)
|
||||
delegate!(fn abs(n: c_double) -> c_double = cmath::c_double_utils::abs)
|
||||
delegate!(fn abs_sub(a: c_double, b: c_double) -> c_double =
|
||||
cmath::c_double_utils::abs_sub)
|
||||
delegate!(fn floor(n: c_double) -> c_double = cmath::c_double_utils::floor)
|
||||
delegate!(fn mul_add(a: c_double, b: c_double, c: c_double) -> c_double =
|
||||
cmath::c_double_utils::mul_add)
|
||||
delegate!(fn fmax(a: c_double, b: c_double) -> c_double =
|
||||
cmath::c_double_utils::fmax)
|
||||
delegate!(fn fmin(a: c_double, b: c_double) -> c_double =
|
||||
cmath::c_double_utils::fmin)
|
||||
delegate!(fn nextafter(x: c_double, y: c_double) -> c_double =
|
||||
cmath::c_double_utils::nextafter)
|
||||
delegate!(fn frexp(n: c_double, value: &mut c_int) -> c_double =
|
||||
cmath::c_double_utils::frexp)
|
||||
delegate!(fn hypot(x: c_double, y: c_double) -> c_double =
|
||||
cmath::c_double_utils::hypot)
|
||||
delegate!(fn ldexp(x: c_double, n: c_int) -> c_double =
|
||||
cmath::c_double_utils::ldexp)
|
||||
delegate!(fn lgamma(n: c_double, sign: &mut c_int) -> c_double =
|
||||
cmath::c_double_utils::lgamma)
|
||||
delegate!(fn ln(n: c_double) -> c_double = cmath::c_double_utils::ln)
|
||||
delegate!(fn log_radix(n: c_double) -> c_double =
|
||||
cmath::c_double_utils::log_radix)
|
||||
delegate!(fn ln1p(n: c_double) -> c_double = cmath::c_double_utils::ln1p)
|
||||
delegate!(fn log10(n: c_double) -> c_double = cmath::c_double_utils::log10)
|
||||
delegate!(fn log2(n: c_double) -> c_double = cmath::c_double_utils::log2)
|
||||
delegate!(fn ilog_radix(n: c_double) -> c_int =
|
||||
cmath::c_double_utils::ilog_radix)
|
||||
delegate!(fn modf(n: c_double, iptr: &mut c_double) -> c_double =
|
||||
cmath::c_double_utils::modf)
|
||||
delegate!(fn pow(n: c_double, e: c_double) -> c_double =
|
||||
cmath::c_double_utils::pow)
|
||||
delegate!(fn round(n: c_double) -> c_double = cmath::c_double_utils::round)
|
||||
delegate!(fn ldexp_radix(n: c_double, i: c_int) -> c_double =
|
||||
cmath::c_double_utils::ldexp_radix)
|
||||
delegate!(fn sin(n: c_double) -> c_double = cmath::c_double_utils::sin)
|
||||
delegate!(fn sinh(n: c_double) -> c_double = cmath::c_double_utils::sinh)
|
||||
delegate!(fn sqrt(n: c_double) -> c_double = cmath::c_double_utils::sqrt)
|
||||
delegate!(fn tan(n: c_double) -> c_double = cmath::c_double_utils::tan)
|
||||
delegate!(fn tanh(n: c_double) -> c_double = cmath::c_double_utils::tanh)
|
||||
delegate!(fn tgamma(n: c_double) -> c_double = cmath::c_double_utils::tgamma)
|
||||
delegate!(fn trunc(n: c_double) -> c_double = cmath::c_double_utils::trunc)
|
||||
delegate!(fn j0(n: c_double) -> c_double = cmath::c_double_utils::j0)
|
||||
delegate!(fn j1(n: c_double) -> c_double = cmath::c_double_utils::j1)
|
||||
delegate!(fn jn(i: c_int, n: c_double) -> c_double =
|
||||
cmath::c_double_utils::jn)
|
||||
delegate!(fn y0(n: c_double) -> c_double = cmath::c_double_utils::y0)
|
||||
delegate!(fn y1(n: c_double) -> c_double = cmath::c_double_utils::y1)
|
||||
delegate!(fn yn(i: c_int, n: c_double) -> c_double =
|
||||
cmath::c_double_utils::yn)
|
||||
|
||||
// FIXME (#1433): obtain these in a different way
|
||||
|
||||
// These are not defined inside consts:: for consistency with
|
||||
@@ -73,10 +156,6 @@
|
||||
|
||||
pub pure fn gt(x: f64, y: f64) -> bool { return x > y; }
|
||||
|
||||
pub pure fn sqrt(x: f64) -> f64 {
|
||||
cmath::c_double_utils::sqrt(x as libc::c_double) as f64
|
||||
}
|
||||
|
||||
/// Returns true if `x` is a positive number, including +0.0f640 and +Infinity
|
||||
pub pure fn is_positive(x: f64) -> bool
|
||||
{ return x > 0.0f64 || (1.0f64/x) == infinity; }
|
||||
|
||||
@@ -25,15 +25,15 @@
|
||||
use vec;
|
||||
|
||||
extern mod rustrt {
|
||||
fn tdefl_compress_mem_to_heap(psrc_buf: *const c_void,
|
||||
src_buf_len: size_t,
|
||||
pout_len: *size_t,
|
||||
flags: c_int) -> *c_void;
|
||||
unsafe fn tdefl_compress_mem_to_heap(psrc_buf: *const c_void,
|
||||
src_buf_len: size_t,
|
||||
pout_len: *size_t,
|
||||
flags: c_int) -> *c_void;
|
||||
|
||||
fn tinfl_decompress_mem_to_heap(psrc_buf: *const c_void,
|
||||
src_buf_len: size_t,
|
||||
pout_len: *size_t,
|
||||
flags: c_int) -> *c_void;
|
||||
unsafe fn tinfl_decompress_mem_to_heap(psrc_buf: *const c_void,
|
||||
src_buf_len: size_t,
|
||||
pout_len: *size_t,
|
||||
flags: c_int) -> *c_void;
|
||||
}
|
||||
|
||||
const lz_none : c_int = 0x0; // Huffman-coding only.
|
||||
|
||||
+18
-6
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
|
||||
|
||||
@@ -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
@@ -53,7 +53,7 @@ pub struct Closure {
|
||||
|
||||
extern mod rustrt {
|
||||
#[rust_stack]
|
||||
fn rust_upcall_fail(expr: *c_char, file: *c_char, line: size_t);
|
||||
unsafe fn rust_upcall_fail(expr: *c_char, file: *c_char, line: size_t);
|
||||
}
|
||||
|
||||
/// Compares contents of two pointers using the default method.
|
||||
|
||||
@@ -947,12 +947,12 @@ fn test_spawn_sched_childs_on_same_sched() {
|
||||
#[nolink]
|
||||
#[cfg(test)]
|
||||
extern mod testrt {
|
||||
fn rust_dbg_lock_create() -> *libc::c_void;
|
||||
fn rust_dbg_lock_destroy(lock: *libc::c_void);
|
||||
fn rust_dbg_lock_lock(lock: *libc::c_void);
|
||||
fn rust_dbg_lock_unlock(lock: *libc::c_void);
|
||||
fn rust_dbg_lock_wait(lock: *libc::c_void);
|
||||
fn rust_dbg_lock_signal(lock: *libc::c_void);
|
||||
unsafe fn rust_dbg_lock_create() -> *libc::c_void;
|
||||
unsafe fn rust_dbg_lock_destroy(lock: *libc::c_void);
|
||||
unsafe fn rust_dbg_lock_lock(lock: *libc::c_void);
|
||||
unsafe fn rust_dbg_lock_unlock(lock: *libc::c_void);
|
||||
unsafe fn rust_dbg_lock_wait(lock: *libc::c_void);
|
||||
unsafe fn rust_dbg_lock_signal(lock: *libc::c_void);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
+3
-3
@@ -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
@@ -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(); }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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
@@ -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)};
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
@@ -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
@@ -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
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
@@ -440,25 +440,27 @@ fn trans_call_inner(
|
||||
Some(flag)
|
||||
} else { None };
|
||||
|
||||
let (llfn, llenv) = match callee.data {
|
||||
Fn(d) => {
|
||||
(d.llfn, llvm::LLVMGetUndef(T_opaque_box_ptr(ccx)))
|
||||
}
|
||||
Method(d) => {
|
||||
// Weird but true: we pass self in the *environment* slot!
|
||||
let llself = PointerCast(bcx, d.llself,
|
||||
T_opaque_box_ptr(ccx));
|
||||
(d.llfn, llself)
|
||||
}
|
||||
Closure(d) => {
|
||||
// Closures are represented as (llfn, llclosure) pair:
|
||||
// load the requisite values out.
|
||||
let pair = d.to_ref_llval(bcx);
|
||||
let llfn = GEPi(bcx, pair, [0u, abi::fn_field_code]);
|
||||
let llfn = Load(bcx, llfn);
|
||||
let llenv = GEPi(bcx, pair, [0u, abi::fn_field_box]);
|
||||
let llenv = Load(bcx, llenv);
|
||||
(llfn, llenv)
|
||||
let (llfn, llenv) = unsafe {
|
||||
match callee.data {
|
||||
Fn(d) => {
|
||||
(d.llfn, llvm::LLVMGetUndef(T_opaque_box_ptr(ccx)))
|
||||
}
|
||||
Method(d) => {
|
||||
// Weird but true: we pass self in the *environment* slot!
|
||||
let llself = PointerCast(bcx, d.llself,
|
||||
T_opaque_box_ptr(ccx));
|
||||
(d.llfn, llself)
|
||||
}
|
||||
Closure(d) => {
|
||||
// Closures are represented as (llfn, llclosure) pair:
|
||||
// load the requisite values out.
|
||||
let pair = d.to_ref_llval(bcx);
|
||||
let llfn = GEPi(bcx, pair, [0u, abi::fn_field_code]);
|
||||
let llfn = Load(bcx, llfn);
|
||||
let llenv = GEPi(bcx, pair, [0u, abi::fn_field_box]);
|
||||
let llenv = Load(bcx, llenv);
|
||||
(llfn, llenv)
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -493,8 +495,10 @@ fn trans_call_inner(
|
||||
bcx = base::invoke(bcx, llfn, llargs);
|
||||
match dest { // drop the value if it is not being saved.
|
||||
expr::Ignore => {
|
||||
if llvm::LLVMIsUndef(llretslot) != lib::llvm::True {
|
||||
bcx = glue::drop_ty(bcx, llretslot, ret_ty);
|
||||
unsafe {
|
||||
if llvm::LLVMIsUndef(llretslot) != lib::llvm::True {
|
||||
bcx = glue::drop_ty(bcx, llretslot, ret_ty);
|
||||
}
|
||||
}
|
||||
}
|
||||
expr::SaveIn(_) => { }
|
||||
@@ -545,7 +549,9 @@ fn trans_args(cx: block,
|
||||
expr::SaveIn(dst) => dst,
|
||||
expr::Ignore => {
|
||||
if ty::type_is_nil(retty) {
|
||||
llvm::LLVMGetUndef(T_ptr(T_nil()))
|
||||
unsafe {
|
||||
llvm::LLVMGetUndef(T_ptr(T_nil()))
|
||||
}
|
||||
} else {
|
||||
alloc_ty(bcx, retty)
|
||||
}
|
||||
@@ -662,7 +668,9 @@ fn trans_arg_expr(bcx: block,
|
||||
// be inspected. It's important for the value
|
||||
// to have type lldestty (the callee's expected type).
|
||||
let llformal_ty = type_of::type_of(ccx, formal_ty.ty);
|
||||
val = llvm::LLVMGetUndef(llformal_ty);
|
||||
unsafe {
|
||||
val = llvm::LLVMGetUndef(llformal_ty);
|
||||
}
|
||||
} else {
|
||||
// FIXME(#3548) use the adjustments table
|
||||
match autoref_arg {
|
||||
|
||||
@@ -339,7 +339,9 @@ fn load_environment(fcx: fn_ctxt,
|
||||
let ll =
|
||||
str::as_c_str(~"load_env",
|
||||
|buf|
|
||||
llvm::LLVMAppendBasicBlock(fcx.llfn, buf));
|
||||
unsafe {
|
||||
llvm::LLVMAppendBasicBlock(fcx.llfn, buf)
|
||||
});
|
||||
fcx.llloadenv = Some(ll);
|
||||
ll
|
||||
}
|
||||
|
||||
@@ -137,7 +137,11 @@ fn new_addrspace_gen() -> addrspace_gen {
|
||||
|
||||
struct BuilderRef_res {
|
||||
B: BuilderRef,
|
||||
drop { llvm::LLVMDisposeBuilder(self.B); }
|
||||
drop {
|
||||
unsafe {
|
||||
llvm::LLVMDisposeBuilder(self.B);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn BuilderRef_res(B: BuilderRef) -> BuilderRef_res {
|
||||
@@ -613,7 +617,11 @@ fn ty_str(tn: type_names, t: TypeRef) -> ~str {
|
||||
return lib::llvm::type_to_str(tn, t);
|
||||
}
|
||||
|
||||
fn val_ty(v: ValueRef) -> TypeRef { return llvm::LLVMTypeOf(v); }
|
||||
fn val_ty(v: ValueRef) -> TypeRef {
|
||||
unsafe {
|
||||
return llvm::LLVMTypeOf(v);
|
||||
}
|
||||
}
|
||||
|
||||
fn val_str(tn: type_names, v: ValueRef) -> ~str {
|
||||
return ty_str(tn, val_ty(v));
|
||||
@@ -621,12 +629,15 @@ fn val_str(tn: type_names, v: ValueRef) -> ~str {
|
||||
|
||||
// Returns the nth element of the given LLVM structure type.
|
||||
fn struct_elt(llstructty: TypeRef, n: uint) -> TypeRef unsafe {
|
||||
let elt_count = llvm::LLVMCountStructElementTypes(llstructty) as uint;
|
||||
assert (n < elt_count);
|
||||
let mut elt_tys = vec::from_elem(elt_count, T_nil());
|
||||
llvm::LLVMGetStructElementTypes(llstructty,
|
||||
ptr::to_mut_unsafe_ptr(&mut elt_tys[0]));
|
||||
return llvm::LLVMGetElementType(elt_tys[n]);
|
||||
unsafe {
|
||||
let elt_count = llvm::LLVMCountStructElementTypes(llstructty) as uint;
|
||||
assert (n < elt_count);
|
||||
let mut elt_tys = vec::from_elem(elt_count, T_nil());
|
||||
llvm::LLVMGetStructElementTypes(
|
||||
llstructty,
|
||||
ptr::to_mut_unsafe_ptr(&mut elt_tys[0]));
|
||||
return llvm::LLVMGetElementType(elt_tys[n]);
|
||||
}
|
||||
}
|
||||
|
||||
fn in_scope_cx(cx: block, f: fn(scope_info)) {
|
||||
@@ -722,30 +733,34 @@ fn T_void() -> TypeRef {
|
||||
// of 10 nil values will have 10-bit size -- but it doesn't seem like we
|
||||
// have any other options until it's fixed upstream.
|
||||
|
||||
return llvm::LLVMVoidType();
|
||||
unsafe {
|
||||
return llvm::LLVMVoidType();
|
||||
}
|
||||
}
|
||||
|
||||
fn T_nil() -> TypeRef {
|
||||
// NB: See above in T_void().
|
||||
|
||||
return llvm::LLVMInt1Type();
|
||||
unsafe {
|
||||
return llvm::LLVMInt1Type();
|
||||
}
|
||||
}
|
||||
|
||||
fn T_metadata() -> TypeRef { return llvm::LLVMMetadataType(); }
|
||||
fn T_metadata() -> TypeRef { unsafe { return llvm::LLVMMetadataType(); } }
|
||||
|
||||
fn T_i1() -> TypeRef { return llvm::LLVMInt1Type(); }
|
||||
fn T_i1() -> TypeRef { unsafe { return llvm::LLVMInt1Type(); } }
|
||||
|
||||
fn T_i8() -> TypeRef { return llvm::LLVMInt8Type(); }
|
||||
fn T_i8() -> TypeRef { unsafe { return llvm::LLVMInt8Type(); } }
|
||||
|
||||
fn T_i16() -> TypeRef { return llvm::LLVMInt16Type(); }
|
||||
fn T_i16() -> TypeRef { unsafe { return llvm::LLVMInt16Type(); } }
|
||||
|
||||
fn T_i32() -> TypeRef { return llvm::LLVMInt32Type(); }
|
||||
fn T_i32() -> TypeRef { unsafe { return llvm::LLVMInt32Type(); } }
|
||||
|
||||
fn T_i64() -> TypeRef { return llvm::LLVMInt64Type(); }
|
||||
fn T_i64() -> TypeRef { unsafe { return llvm::LLVMInt64Type(); } }
|
||||
|
||||
fn T_f32() -> TypeRef { return llvm::LLVMFloatType(); }
|
||||
fn T_f32() -> TypeRef { unsafe { return llvm::LLVMFloatType(); } }
|
||||
|
||||
fn T_f64() -> TypeRef { return llvm::LLVMDoubleType(); }
|
||||
fn T_f64() -> TypeRef { unsafe { return llvm::LLVMDoubleType(); } }
|
||||
|
||||
fn T_bool() -> TypeRef { return T_i1(); }
|
||||
|
||||
@@ -811,25 +826,39 @@ fn T_fn_pair(cx: @crate_ctxt, tfn: TypeRef) -> TypeRef {
|
||||
}
|
||||
|
||||
fn T_ptr(t: TypeRef) -> TypeRef {
|
||||
return llvm::LLVMPointerType(t, default_addrspace);
|
||||
unsafe {
|
||||
return llvm::LLVMPointerType(t, default_addrspace);
|
||||
}
|
||||
}
|
||||
|
||||
fn T_root(t: TypeRef, addrspace: addrspace) -> TypeRef {
|
||||
return llvm::LLVMPointerType(t, addrspace);
|
||||
unsafe {
|
||||
return llvm::LLVMPointerType(t, addrspace);
|
||||
}
|
||||
}
|
||||
|
||||
fn T_struct(elts: ~[TypeRef]) -> TypeRef unsafe {
|
||||
return llvm::LLVMStructType(to_ptr(elts), elts.len() as c_uint, False);
|
||||
unsafe {
|
||||
return llvm::LLVMStructType(to_ptr(elts),
|
||||
elts.len() as c_uint,
|
||||
False);
|
||||
}
|
||||
}
|
||||
|
||||
fn T_named_struct(name: ~str) -> TypeRef {
|
||||
let c = llvm::LLVMGetGlobalContext();
|
||||
return str::as_c_str(name, |buf| llvm::LLVMStructCreateNamed(c, buf));
|
||||
unsafe {
|
||||
let c = llvm::LLVMGetGlobalContext();
|
||||
return str::as_c_str(name, |buf| llvm::LLVMStructCreateNamed(c, buf));
|
||||
}
|
||||
}
|
||||
|
||||
fn set_struct_body(t: TypeRef, elts: ~[TypeRef]) unsafe {
|
||||
llvm::LLVMStructSetBody(t, to_ptr(elts),
|
||||
elts.len() as c_uint, False);
|
||||
unsafe {
|
||||
llvm::LLVMStructSetBody(t,
|
||||
to_ptr(elts),
|
||||
elts.len() as c_uint,
|
||||
False);
|
||||
}
|
||||
}
|
||||
|
||||
fn T_empty_struct() -> TypeRef { return T_struct(~[]); }
|
||||
@@ -865,14 +894,16 @@ fn T_task(targ_cfg: @session::config) -> TypeRef {
|
||||
fn T_tydesc_field(cx: @crate_ctxt, field: uint) -> TypeRef unsafe {
|
||||
// Bit of a kludge: pick the fn typeref out of the tydesc..
|
||||
|
||||
let mut tydesc_elts: ~[TypeRef] =
|
||||
vec::from_elem::<TypeRef>(abi::n_tydesc_fields,
|
||||
T_nil());
|
||||
llvm::LLVMGetStructElementTypes(
|
||||
cx.tydesc_type,
|
||||
ptr::to_mut_unsafe_ptr(&mut tydesc_elts[0]));
|
||||
let t = llvm::LLVMGetElementType(tydesc_elts[field]);
|
||||
return t;
|
||||
unsafe {
|
||||
let mut tydesc_elts: ~[TypeRef] =
|
||||
vec::from_elem::<TypeRef>(abi::n_tydesc_fields,
|
||||
T_nil());
|
||||
llvm::LLVMGetStructElementTypes(
|
||||
cx.tydesc_type,
|
||||
ptr::to_mut_unsafe_ptr(&mut tydesc_elts[0]));
|
||||
let t = llvm::LLVMGetElementType(tydesc_elts[field]);
|
||||
return t;
|
||||
}
|
||||
}
|
||||
|
||||
fn T_generic_glue_fn(cx: @crate_ctxt) -> TypeRef {
|
||||
@@ -904,7 +935,9 @@ fn T_tydesc(targ_cfg: @session::config) -> TypeRef {
|
||||
}
|
||||
|
||||
fn T_array(t: TypeRef, n: uint) -> TypeRef {
|
||||
return llvm::LLVMArrayType(t, n as c_uint);
|
||||
unsafe {
|
||||
return llvm::LLVMArrayType(t, n as c_uint);
|
||||
}
|
||||
}
|
||||
|
||||
// Interior vector.
|
||||
@@ -947,7 +980,9 @@ fn T_box(cx: @crate_ctxt, t: TypeRef) -> TypeRef {
|
||||
}
|
||||
|
||||
fn T_box_ptr(t: TypeRef) -> TypeRef {
|
||||
return llvm::LLVMPointerType(t, gc_box_addrspace);
|
||||
unsafe {
|
||||
return llvm::LLVMPointerType(t, gc_box_addrspace);
|
||||
}
|
||||
}
|
||||
|
||||
fn T_opaque_box(cx: @crate_ctxt) -> TypeRef {
|
||||
@@ -963,7 +998,9 @@ fn T_unique(cx: @crate_ctxt, t: TypeRef) -> TypeRef {
|
||||
}
|
||||
|
||||
fn T_unique_ptr(t: TypeRef) -> TypeRef {
|
||||
return llvm::LLVMPointerType(t, gc_box_addrspace);
|
||||
unsafe {
|
||||
return llvm::LLVMPointerType(t, gc_box_addrspace);
|
||||
}
|
||||
}
|
||||
|
||||
fn T_port(cx: @crate_ctxt, _t: TypeRef) -> TypeRef {
|
||||
@@ -1042,14 +1079,22 @@ fn T_opaque_trait(cx: @crate_ctxt, vstore: ty::vstore) -> TypeRef {
|
||||
|
||||
|
||||
// LLVM constant constructors.
|
||||
fn C_null(t: TypeRef) -> ValueRef { return llvm::LLVMConstNull(t); }
|
||||
fn C_null(t: TypeRef) -> ValueRef {
|
||||
unsafe {
|
||||
return llvm::LLVMConstNull(t);
|
||||
}
|
||||
}
|
||||
|
||||
fn C_integral(t: TypeRef, u: u64, sign_extend: Bool) -> ValueRef {
|
||||
return llvm::LLVMConstInt(t, u, sign_extend);
|
||||
unsafe {
|
||||
return llvm::LLVMConstInt(t, u, sign_extend);
|
||||
}
|
||||
}
|
||||
|
||||
fn C_floating(s: ~str, t: TypeRef) -> ValueRef {
|
||||
return str::as_c_str(s, |buf| llvm::LLVMConstRealOfString(t, buf));
|
||||
unsafe {
|
||||
return str::as_c_str(s, |buf| llvm::LLVMConstRealOfString(t, buf));
|
||||
}
|
||||
}
|
||||
|
||||
fn C_nil() -> ValueRef {
|
||||
@@ -1084,92 +1129,115 @@ fn C_uint(cx: @crate_ctxt, i: uint) -> ValueRef {
|
||||
// This is a 'c-like' raw string, which differs from
|
||||
// our boxed-and-length-annotated strings.
|
||||
fn C_cstr(cx: @crate_ctxt, +s: ~str) -> ValueRef {
|
||||
match cx.const_cstr_cache.find(s) {
|
||||
Some(llval) => return llval,
|
||||
None => ()
|
||||
unsafe {
|
||||
match cx.const_cstr_cache.find(s) {
|
||||
Some(llval) => return llval,
|
||||
None => ()
|
||||
}
|
||||
|
||||
let sc = do str::as_c_str(s) |buf| {
|
||||
llvm::LLVMConstString(buf, str::len(s) as c_uint, False)
|
||||
};
|
||||
let g =
|
||||
str::as_c_str(fmt!("str%u", (cx.names)(~"str").repr),
|
||||
|buf| llvm::LLVMAddGlobal(cx.llmod, val_ty(sc), buf));
|
||||
llvm::LLVMSetInitializer(g, sc);
|
||||
llvm::LLVMSetGlobalConstant(g, True);
|
||||
lib::llvm::SetLinkage(g, lib::llvm::InternalLinkage);
|
||||
|
||||
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
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -186,12 +186,15 @@ fn trans_log(log_ex: @ast::expr,
|
||||
} else {
|
||||
let s = link::mangle_internal_name_by_path_and_seq(
|
||||
ccx, modpath, ~"loglevel");
|
||||
let global = str::as_c_str(s, |buf| {
|
||||
llvm::LLVMAddGlobal(ccx.llmod, T_i32(), buf)
|
||||
});
|
||||
llvm::LLVMSetGlobalConstant(global, False);
|
||||
llvm::LLVMSetInitializer(global, C_null(T_i32()));
|
||||
lib::llvm::SetLinkage(global, lib::llvm::InternalLinkage);
|
||||
let global;
|
||||
unsafe {
|
||||
global = str::as_c_str(s, |buf| {
|
||||
llvm::LLVMAddGlobal(ccx.llmod, T_i32(), buf)
|
||||
});
|
||||
llvm::LLVMSetGlobalConstant(global, False);
|
||||
llvm::LLVMSetInitializer(global, C_null(T_i32()));
|
||||
lib::llvm::SetLinkage(global, lib::llvm::InternalLinkage);
|
||||
}
|
||||
ccx.module_data.insert(modname, global);
|
||||
global
|
||||
};
|
||||
|
||||
@@ -69,7 +69,9 @@
|
||||
|
||||
fn llstr(s: ~str) -> ValueRef {
|
||||
str::as_c_str(s, |sbuf| {
|
||||
llvm::LLVMMDString(sbuf, str::len(s) as libc::c_uint)
|
||||
unsafe {
|
||||
llvm::LLVMMDString(sbuf, str::len(s) as libc::c_uint)
|
||||
}
|
||||
})
|
||||
}
|
||||
fn lltag(lltag: int) -> ValueRef {
|
||||
@@ -85,8 +87,10 @@ fn lli1(bval: bool) -> ValueRef {
|
||||
C_bool(bval)
|
||||
}
|
||||
fn llmdnode(elems: ~[ValueRef]) -> ValueRef unsafe {
|
||||
llvm::LLVMMDNode(vec::raw::to_ptr(elems),
|
||||
vec::len(elems) as libc::c_uint)
|
||||
unsafe {
|
||||
llvm::LLVMMDNode(vec::raw::to_ptr(elems),
|
||||
vec::len(elems) as libc::c_uint)
|
||||
}
|
||||
}
|
||||
fn llunused() -> ValueRef {
|
||||
lli32(0x0)
|
||||
@@ -97,7 +101,9 @@ fn llnull() -> ValueRef unsafe {
|
||||
|
||||
fn add_named_metadata(cx: @crate_ctxt, name: ~str, val: ValueRef) {
|
||||
str::as_c_str(name, |sbuf| {
|
||||
llvm::LLVMAddNamedMetadataOperand(cx.llmod, sbuf, val)
|
||||
unsafe {
|
||||
llvm::LLVMAddNamedMetadataOperand(cx.llmod, sbuf, val)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -744,7 +750,9 @@ fn update_source_pos(cx: block, s: span) {
|
||||
blockmd.node,
|
||||
llnull()];
|
||||
let dbgscope = llmdnode(scopedata);
|
||||
llvm::LLVMSetCurrentDebugLocation(trans::build::B(cx), dbgscope);
|
||||
unsafe {
|
||||
llvm::LLVMSetCurrentDebugLocation(trans::build::B(cx), dbgscope);
|
||||
}
|
||||
}
|
||||
|
||||
fn create_function(fcx: fn_ctxt) -> @metadata<subprogram_md> {
|
||||
|
||||
@@ -1483,15 +1483,19 @@ fn trans_overloaded_op(bcx: block,
|
||||
fn int_cast(bcx: block, lldsttype: TypeRef, llsrctype: TypeRef,
|
||||
llsrc: ValueRef, signed: bool) -> ValueRef {
|
||||
let _icx = bcx.insn_ctxt("int_cast");
|
||||
let srcsz = llvm::LLVMGetIntTypeWidth(llsrctype);
|
||||
let dstsz = llvm::LLVMGetIntTypeWidth(lldsttype);
|
||||
return if dstsz == srcsz {
|
||||
BitCast(bcx, llsrc, lldsttype)
|
||||
} else if srcsz > dstsz {
|
||||
TruncOrBitCast(bcx, llsrc, lldsttype)
|
||||
} else if signed {
|
||||
SExtOrBitCast(bcx, llsrc, lldsttype)
|
||||
} else { ZExtOrBitCast(bcx, llsrc, lldsttype) };
|
||||
unsafe {
|
||||
let srcsz = llvm::LLVMGetIntTypeWidth(llsrctype);
|
||||
let dstsz = llvm::LLVMGetIntTypeWidth(lldsttype);
|
||||
return if dstsz == srcsz {
|
||||
BitCast(bcx, llsrc, lldsttype)
|
||||
} else if srcsz > dstsz {
|
||||
TruncOrBitCast(bcx, llsrc, lldsttype)
|
||||
} else if signed {
|
||||
SExtOrBitCast(bcx, llsrc, lldsttype)
|
||||
} else {
|
||||
ZExtOrBitCast(bcx, llsrc, lldsttype)
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
fn float_cast(bcx: block, lldsttype: TypeRef, llsrctype: TypeRef,
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
_ => ()
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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],
|
||||
|
||||
@@ -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};
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
@@ -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
@@ -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]
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user