Skip to content

Commit 70d7de8

Browse files
author
Nick Desaulniers
committed
Merge branch 'incoming' of git://github.com/mozilla/rust into removePar
2 parents 4a2e6df + 1175e94 commit 70d7de8

File tree

37 files changed

+455
-333
lines changed

37 files changed

+455
-333
lines changed

doc/tutorial-tasks.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -318,7 +318,7 @@ be distributed on the available cores.
318318
fn partial_sum(start: uint) -> f64 {
319319
let mut local_sum = 0f64;
320320
for uint::range(start*100000, (start+1)*100000) |num| {
321-
local_sum += (num as f64 + 1.0).pow(-2.0);
321+
local_sum += (num as f64 + 1.0).pow(&-2.0);
322322
}
323323
local_sum
324324
}
@@ -355,7 +355,7 @@ a single large vector of floats. Each task needs the full vector to perform its
355355
use extra::arc::ARC;
356356
357357
fn pnorm(nums: &~[float], p: uint) -> float {
358-
nums.iter().fold(0.0, |a,b| a+(*b).pow(p as float) ).pow(1f / (p as float))
358+
nums.iter().fold(0.0, |a,b| a+(*b).pow(&(p as float)) ).pow(&(1f / (p as float)))
359359
}
360360
361361
fn main() {

src/libextra/getopts.rs

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -31,21 +31,22 @@
3131
* file name following -o, and accepts both -h and --help as optional flags.
3232
*
3333
* ```
34-
* extern mod std;
35-
* use std::getopts::*;
34+
* extern mod extra;
35+
* use extra::getopts::*;
36+
* use std::os;
3637
*
3738
* fn do_work(in: &str, out: Option<~str>) {
38-
* io::println(in);
39-
* io::println(match out {
40-
* Some(x) => x,
41-
* None => ~"No Output"
42-
* });
39+
* println(in);
40+
* println(match out {
41+
* Some(x) => x,
42+
* None => ~"No Output"
43+
* });
4344
* }
4445
*
45-
* fn print_usage(program: &str, _opts: &[std::getopts::Opt]) {
46-
* io::println(fmt!("Usage: %s [options]", program));
47-
* io::println("-o\t\tOutput");
48-
* io::println("-h --help\tUsage");
46+
* fn print_usage(program: &str, _opts: &[Opt]) {
47+
* println(fmt!("Usage: %s [options]", program));
48+
* println("-o\t\tOutput");
49+
* println("-h --help\tUsage");
4950
* }
5051
*
5152
* fn main() {
@@ -58,9 +59,9 @@
5859
* optflag("h"),
5960
* optflag("help")
6061
* ];
61-
* let matches = match getopts(vec::tail(args), opts) {
62-
* result::Ok(m) => { m }
63-
* result::Err(f) => { fail!(fail_str(f)) }
62+
* let matches = match getopts(args.tail(), opts) {
63+
* Ok(m) => { m }
64+
* Err(f) => { fail!(fail_str(f)) }
6465
* };
6566
* if opt_present(&matches, "h") || opt_present(&matches, "help") {
6667
* print_usage(program, opts);

src/libextra/num/complex.rs

Lines changed: 63 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ pub type Complex = Cmplx<float>;
3535
pub type Complex32 = Cmplx<f32>;
3636
pub type Complex64 = Cmplx<f64>;
3737

38-
impl<T: Copy + Num> Cmplx<T> {
38+
impl<T: Clone + Num> Cmplx<T> {
3939
/// Create a new Cmplx
4040
#[inline]
4141
pub fn new(re: T, im: T) -> Cmplx<T> {
@@ -55,7 +55,7 @@ impl<T: Copy + Num> Cmplx<T> {
5555
/// Returns the complex conjugate. i.e. `re - i im`
5656
#[inline]
5757
pub fn conj(&self) -> Cmplx<T> {
58-
Cmplx::new(self.re, -self.im)
58+
Cmplx::new(self.re.clone(), -self.im)
5959
}
6060

6161

@@ -80,62 +80,91 @@ impl<T: Copy + Num> Cmplx<T> {
8080
}
8181
}
8282

83+
#[cfg(not(stage0))] // Fixed by #4228
84+
impl<T: Clone + Algebraic + Num> Cmplx<T> {
85+
/// Calculate |self|
86+
#[inline(always)]
87+
pub fn norm(&self) -> T {
88+
self.re.hypot(&self.im)
89+
}
90+
}
91+
92+
#[cfg(not(stage0))] // Fixed by #4228
93+
impl<T: Clone + Trigonometric + Algebraic + Num> Cmplx<T> {
94+
/// Calculate the principal Arg of self.
95+
#[inline(always)]
96+
pub fn arg(&self) -> T {
97+
self.im.atan2(&self.re)
98+
}
99+
/// Convert to polar form (r, theta), such that `self = r * exp(i
100+
/// * theta)`
101+
#[inline]
102+
pub fn to_polar(&self) -> (T, T) {
103+
(self.norm(), self.arg())
104+
}
105+
/// Convert a polar representation into a complex number.
106+
#[inline]
107+
pub fn from_polar(r: &T, theta: &T) -> Cmplx<T> {
108+
Cmplx::new(r * theta.cos(), r * theta.sin())
109+
}
110+
}
111+
83112
/* arithmetic */
84113
// (a + i b) + (c + i d) == (a + c) + i (b + d)
85-
impl<T: Copy + Num> Add<Cmplx<T>, Cmplx<T>> for Cmplx<T> {
114+
impl<T: Clone + Num> Add<Cmplx<T>, Cmplx<T>> for Cmplx<T> {
86115
#[inline]
87116
fn add(&self, other: &Cmplx<T>) -> Cmplx<T> {
88117
Cmplx::new(self.re + other.re, self.im + other.im)
89118
}
90119
}
91120
// (a + i b) - (c + i d) == (a - c) + i (b - d)
92-
impl<T: Copy + Num> Sub<Cmplx<T>, Cmplx<T>> for Cmplx<T> {
121+
impl<T: Clone + Num> Sub<Cmplx<T>, Cmplx<T>> for Cmplx<T> {
93122
#[inline]
94123
fn sub(&self, other: &Cmplx<T>) -> Cmplx<T> {
95124
Cmplx::new(self.re - other.re, self.im - other.im)
96125
}
97126
}
98127
// (a + i b) * (c + i d) == (a*c - b*d) + i (a*d + b*c)
99-
impl<T: Copy + Num> Mul<Cmplx<T>, Cmplx<T>> for Cmplx<T> {
128+
impl<T: Clone + Num> Mul<Cmplx<T>, Cmplx<T>> for Cmplx<T> {
100129
#[inline]
101130
fn mul(&self, other: &Cmplx<T>) -> Cmplx<T> {
102131
Cmplx::new(self.re*other.re - self.im*other.im,
103-
self.re*other.im + self.im*other.re)
132+
self.re*other.im + self.im*other.re)
104133
}
105134
}
106135

107136
// (a + i b) / (c + i d) == [(a + i b) * (c - i d)] / (c*c + d*d)
108137
// == [(a*c + b*d) / (c*c + d*d)] + i [(b*c - a*d) / (c*c + d*d)]
109-
impl<T: Copy + Num> Div<Cmplx<T>, Cmplx<T>> for Cmplx<T> {
138+
impl<T: Clone + Num> Div<Cmplx<T>, Cmplx<T>> for Cmplx<T> {
110139
#[inline]
111140
fn div(&self, other: &Cmplx<T>) -> Cmplx<T> {
112141
let norm_sqr = other.norm_sqr();
113142
Cmplx::new((self.re*other.re + self.im*other.im) / norm_sqr,
114-
(self.im*other.re - self.re*other.im) / norm_sqr)
143+
(self.im*other.re - self.re*other.im) / norm_sqr)
115144
}
116145
}
117146

118-
impl<T: Copy + Num> Neg<Cmplx<T>> for Cmplx<T> {
147+
impl<T: Clone + Num> Neg<Cmplx<T>> for Cmplx<T> {
119148
#[inline]
120149
fn neg(&self) -> Cmplx<T> {
121150
Cmplx::new(-self.re, -self.im)
122151
}
123152
}
124153

125154
/* constants */
126-
impl<T: Copy + Num> Zero for Cmplx<T> {
155+
impl<T: Clone + Num> Zero for Cmplx<T> {
127156
#[inline]
128157
fn zero() -> Cmplx<T> {
129158
Cmplx::new(Zero::zero(), Zero::zero())
130159
}
131160

132161
#[inline]
133162
fn is_zero(&self) -> bool {
134-
*self == Zero::zero()
163+
self.re.is_zero() && self.im.is_zero()
135164
}
136165
}
137166

138-
impl<T: Copy + Num> One for Cmplx<T> {
167+
impl<T: Clone + Num> One for Cmplx<T> {
139168
#[inline]
140169
fn one() -> Cmplx<T> {
141170
Cmplx::new(One::one(), Zero::zero())
@@ -166,7 +195,7 @@ impl<T: ToStrRadix + Num + Ord> ToStrRadix for Cmplx<T> {
166195
#[cfg(test)]
167196
mod test {
168197
use super::*;
169-
use core::num::{Zero,One};
198+
use core::num::{Zero,One,Real};
170199

171200
pub static _0_0i : Complex = Cmplx { re: 0f, im: 0f };
172201
pub static _1_0i : Complex = Cmplx { re: 1f, im: 0f };
@@ -193,9 +222,10 @@ mod test {
193222
}
194223

195224
#[test]
196-
fn test_norm_sqr() {
225+
fn test_norm() {
197226
fn test(c: Complex, ns: float) {
198227
assert_eq!(c.norm_sqr(), ns);
228+
assert_eq!(c.norm(), ns.sqrt())
199229
}
200230
test(_0_0i, 0f);
201231
test(_1_0i, 1f);
@@ -235,6 +265,25 @@ mod test {
235265
_0_0i.inv();
236266
}
237267

268+
#[test]
269+
fn test_arg() {
270+
fn test(c: Complex, arg: float) {
271+
assert!(c.arg().approx_eq(&arg))
272+
}
273+
test(_1_0i, 0f);
274+
test(_1_1i, 0.25f * Real::pi());
275+
test(_neg1_1i, 0.75f * Real::pi());
276+
test(_05_05i, 0.25f * Real::pi());
277+
}
278+
279+
#[test]
280+
fn test_polar_conv() {
281+
fn test(c: Complex) {
282+
let (r, theta) = c.to_polar();
283+
assert!((c - Cmplx::from_polar(&r, &theta)).norm() < 1e-6);
284+
}
285+
for all_consts.each |&c| { test(c); }
286+
}
238287

239288
mod arith {
240289
use super::*;

src/libextra/terminfo/searcher.rs

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,13 @@ pub fn get_dbpath_for_term(term: &str) -> Option<~path> {
4444
dirs_to_search.push(path(i.to_owned()));
4545
}
4646
},
47-
// Found nothing, use the default path
48-
None => dirs_to_search.push(path("/usr/share/terminfo"))
47+
// Found nothing, use the default paths
48+
// /usr/share/terminfo is the de facto location, but it seems
49+
// Ubuntu puts it in /lib/terminfo
50+
None => {
51+
dirs_to_search.push(path("/usr/share/terminfo"));
52+
dirs_to_search.push(path("/lib/terminfo"));
53+
}
4954
}
5055
}
5156
};
@@ -56,6 +61,11 @@ pub fn get_dbpath_for_term(term: &str) -> Option<~path> {
5661
if os::path_exists(p) && os::path_exists(newp) {
5762
return Some(newp);
5863
}
64+
// on some installations the dir is named after the hex of the char (e.g. OS X)
65+
let newp = ~p.push_many(&[fmt!("%x", first_char[0] as uint), term.to_owned()]);
66+
if os::path_exists(p) && os::path_exists(newp) {
67+
return Some(newp);
68+
}
5969
}
6070
None
6171
}
@@ -72,6 +82,7 @@ pub fn open(term: &str) -> Result<@Reader, ~str> {
7282
#[ignore(reason = "buildbots don't have ncurses installed and I can't mock everything I need")]
7383
fn test_get_dbpath_for_term() {
7484
// woefully inadequate test coverage
85+
// note: current tests won't work with non-standard terminfo hierarchies (e.g. OS X's)
7586
use std::os::{setenv, unsetenv};
7687
fn x(t: &str) -> ~str { get_dbpath_for_term(t).expect("no terminfo entry found").to_str() };
7788
assert!(x("screen") == ~"/usr/share/terminfo/s/screen");

src/libextra/timer.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,6 @@ pub fn recv_timeout<T:Copy + Owned>(iotask: &IoTask,
131131
unsafe {
132132
let wait_po = cast::transmute_mut(wait_po);
133133

134-
// FIXME: This could be written clearer (#2618)
135134
either::either(
136135
|_| {
137136
None

src/librustc/back/link.rs

Lines changed: 42 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ pub mod jit {
103103
use back::link::llvm_err;
104104
use driver::session::Session;
105105
use lib::llvm::llvm;
106-
use lib::llvm::{ModuleRef, PassManagerRef};
106+
use lib::llvm::{ModuleRef, PassManagerRef, ContextRef};
107107
use metadata::cstore;
108108

109109
use core::cast;
@@ -126,6 +126,7 @@ pub mod jit {
126126

127127
pub fn exec(sess: Session,
128128
pm: PassManagerRef,
129+
c: ContextRef,
129130
m: ModuleRef,
130131
opt: c_int,
131132
stacks: bool) {
@@ -154,26 +155,43 @@ pub mod jit {
154155
});
155156
}
156157

157-
// The execute function will return a void pointer
158-
// to the _rust_main function. We can do closure
159-
// magic here to turn it straight into a callable rust
160-
// closure. It will also cleanup the memory manager
161-
// for us.
162-
163-
let entry = llvm::LLVMRustExecuteJIT(manager,
164-
pm, m, opt, stacks);
165-
166-
if ptr::is_null(entry) {
167-
llvm_err(sess, ~"Could not JIT");
168-
} else {
169-
let closure = Closure {
170-
code: entry,
171-
env: ptr::null()
172-
};
173-
let func: &fn() = cast::transmute(closure);
158+
// We custom-build a JIT execution engine via some rust wrappers
159+
// first. This wrappers takes ownership of the module passed in.
160+
let ee = llvm::LLVMRustBuildJIT(manager, pm, m, opt, stacks);
161+
if ee.is_null() {
162+
llvm::LLVMContextDispose(c);
163+
llvm_err(sess, ~"Could not create the JIT");
164+
}
174165

175-
func();
166+
// Next, we need to get a handle on the _rust_main function by
167+
// looking up it's corresponding ValueRef and then requesting that
168+
// the execution engine compiles the function.
169+
let fun = do str::as_c_str("_rust_main") |entry| {
170+
llvm::LLVMGetNamedFunction(m, entry)
171+
};
172+
if fun.is_null() {
173+
llvm::LLVMDisposeExecutionEngine(ee);
174+
llvm::LLVMContextDispose(c);
175+
llvm_err(sess, ~"Could not find _rust_main in the JIT");
176176
}
177+
178+
// Finally, once we have the pointer to the code, we can do some
179+
// closure magic here to turn it straight into a callable rust
180+
// closure
181+
let code = llvm::LLVMGetPointerToGlobal(ee, fun);
182+
assert!(!code.is_null());
183+
let closure = Closure {
184+
code: code,
185+
env: ptr::null()
186+
};
187+
let func: &fn() = cast::transmute(closure);
188+
func();
189+
190+
// Sadly, there currently is no interface to re-use this execution
191+
// engine, so it's disposed of here along with the context to
192+
// prevent leaks.
193+
llvm::LLVMDisposeExecutionEngine(ee);
194+
llvm::LLVMContextDispose(c);
177195
}
178196
}
179197
}
@@ -190,6 +208,7 @@ pub mod write {
190208
use driver::session;
191209
use lib::llvm::llvm;
192210
use lib::llvm::{ModuleRef, mk_pass_manager, mk_target_data};
211+
use lib::llvm::{False, ContextRef};
193212
use lib;
194213

195214
use back::passes;
@@ -208,6 +227,7 @@ pub mod write {
208227
}
209228

210229
pub fn run_passes(sess: Session,
230+
llcx: ContextRef,
211231
llmod: ModuleRef,
212232
output_type: output_type,
213233
output: &Path) {
@@ -282,7 +302,7 @@ pub mod write {
282302
// JIT execution takes ownership of the module,
283303
// so don't dispose and return.
284304

285-
jit::exec(sess, pm.llpm, llmod, CodeGenOptLevel, true);
305+
jit::exec(sess, pm.llpm, llcx, llmod, CodeGenOptLevel, true);
286306

287307
if sess.time_llvm_passes() {
288308
llvm::LLVMRustPrintPassTimings();
@@ -350,6 +370,7 @@ pub mod write {
350370
// Clean up and return
351371

352372
llvm::LLVMDisposeModule(llmod);
373+
llvm::LLVMContextDispose(llcx);
353374
if sess.time_llvm_passes() {
354375
llvm::LLVMRustPrintPassTimings();
355376
}
@@ -368,6 +389,7 @@ pub mod write {
368389
}
369390

370391
llvm::LLVMDisposeModule(llmod);
392+
llvm::LLVMContextDispose(llcx);
371393
if sess.time_llvm_passes() { llvm::LLVMRustPrintPassTimings(); }
372394
}
373395
}

0 commit comments

Comments
 (0)