Skip to content

Commit 0eb757a

Browse files
committed
---
yaml --- r: 126175 b: refs/heads/master c: 795f6ae h: refs/heads/master i: 126173: e6f2f88 126171: 34e2743 126167: 3596ba5 126159: 1c68090 126143: 7a77a68 v: v3
1 parent b51c8a2 commit 0eb757a

File tree

12 files changed

+229
-50
lines changed

12 files changed

+229
-50
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
---
2-
refs/heads/master: e753dbb431534b4b07b2724d7bbbcef59ecbd4d3
2+
refs/heads/master: 795f6ae829ab1bfd72394a5da9096e2717ec0f62
33
refs/heads/snap-stage1: e33de59e47c5076a89eadeb38f4934f58a3618a6
44
refs/heads/snap-stage3: 9fc8394d3bce22ab483f98842434c84c396212ae
55
refs/heads/try: f36ed4b00bccd0087bfffb6847d0d69cc18c23bd

trunk/.gitignore

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,12 @@
6464
/nd/
6565
/rt/
6666
/rustllvm/
67+
/src/libunicode/DerivedCoreProperties.txt
68+
/src/libunicode/EastAsianWidth.txt
69+
/src/libunicode/HangulSyllableType.txt
70+
/src/libunicode/PropList.txt
71+
/src/libunicode/Scripts.txt
72+
/src/libunicode/UnicodeData.txt
6773
/stage0/
6874
/stage1/
6975
/stage2/

trunk/src/doc/guide.md

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1060,7 +1060,6 @@ you create a new type that's a synonym for another one:
10601060

10611061
```
10621062
struct Inches(int);
1063-
struct Centimeters(int);
10641063
10651064
let length = Inches(10);
10661065
@@ -1627,10 +1626,6 @@ Check out the generated `Cargo.toml`:
16271626
name = "guessing_game"
16281627
version = "0.1.0"
16291628
authors = ["Your Name <[email protected]>"]
1630-
1631-
[[bin]]
1632-
1633-
name = "guessing_game"
16341629
```
16351630

16361631
Cargo gets this information from your environment. If it's not correct, go ahead

trunk/src/libcollections/vec.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -964,7 +964,7 @@ impl<T> Vec<T> {
964964
#[inline]
965965
pub fn swap_remove(&mut self, index: uint) -> Option<T> {
966966
let length = self.len();
967-
if index < length - 1 {
967+
if length > 0 && index < length - 1 {
968968
self.as_mut_slice().swap(index, length - 1);
969969
} else if index >= length {
970970
return None
@@ -2003,6 +2003,12 @@ mod tests {
20032003
let _ = vec[3];
20042004
}
20052005

2006+
#[test]
2007+
fn test_swap_remove_empty() {
2008+
let mut vec: Vec<uint> = vec!();
2009+
assert_eq!(vec.swap_remove(0), None);
2010+
}
2011+
20062012
#[bench]
20072013
fn bench_new(b: &mut Bencher) {
20082014
b.iter(|| {

trunk/src/libcore/cmp.rs

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,40 @@ pub enum Ordering {
100100
Greater = 1i,
101101
}
102102

103+
impl Ordering {
104+
/// Reverse the `Ordering`, so that `Less` becomes `Greater` and
105+
/// vice versa.
106+
///
107+
/// # Example
108+
///
109+
/// ```rust
110+
/// assert_eq!(Less.reverse(), Greater);
111+
/// assert_eq!(Equal.reverse(), Equal);
112+
/// assert_eq!(Greater.reverse(), Less);
113+
///
114+
///
115+
/// let mut data = &mut [2u, 10, 5, 8];
116+
///
117+
/// // sort the array from largest to smallest.
118+
/// data.sort_by(|a, b| a.cmp(b).reverse());
119+
///
120+
/// assert_eq!(data, &mut [10u, 8, 5, 2]);
121+
/// ```
122+
#[inline]
123+
#[experimental]
124+
pub fn reverse(self) -> Ordering {
125+
unsafe {
126+
// this compiles really nicely (to a single instruction);
127+
// an explicit match has a pile of branches and
128+
// comparisons.
129+
//
130+
// NB. it is safe because of the explicit discriminants
131+
// given above.
132+
::mem::transmute::<_, Ordering>(-(self as i8))
133+
}
134+
}
135+
}
136+
103137
/// Trait for types that form a [total order](
104138
/// https://en.wikipedia.org/wiki/Total_order).
105139
///

trunk/src/libcore/num/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -279,8 +279,8 @@ pub fn abs<T: Signed>(value: T) -> T {
279279

280280
/// The positive difference of two numbers.
281281
///
282-
/// Returns `zero` if the number is less than or equal to `other`,
283-
/// otherwise the difference between `self` and `other` is returned.
282+
/// Returns zero if `x` is less than or equal to `y`, otherwise the difference
283+
/// between `x` and `y` is returned.
284284
#[inline(always)]
285285
pub fn abs_sub<T: Signed>(x: T, y: T) -> T {
286286
x.abs_sub(&y)

trunk/src/libcoretest/cmp.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,13 @@ fn test_mut_int_totalord() {
2828
assert_eq!((&mut 12i).cmp(&&mut -5), Greater);
2929
}
3030

31+
#[test]
32+
fn test_ordering_reverse() {
33+
assert_eq!(Less.reverse(), Greater);
34+
assert_eq!(Equal.reverse(), Equal);
35+
assert_eq!(Greater.reverse(), Less);
36+
}
37+
3138
#[test]
3239
fn test_ordering_order() {
3340
assert!(Less < Equal);

trunk/src/librustc/back/link.rs

Lines changed: 88 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ use std::char;
3232
use std::collections::HashSet;
3333
use std::io::{fs, TempDir, Command};
3434
use std::io;
35+
use std::mem;
3536
use std::ptr;
3637
use std::str;
3738
use std::string::String;
@@ -45,6 +46,36 @@ use syntax::attr::AttrMetaMethods;
4546
use syntax::codemap::Span;
4647
use syntax::parse::token;
4748

49+
// RLIB LLVM-BYTECODE OBJECT LAYOUT
50+
// Version 1
51+
// Bytes Data
52+
// 0..10 "RUST_OBJECT" encoded in ASCII
53+
// 11..14 format version as little-endian u32
54+
// 15..22 size in bytes of deflate compressed LLVM bitcode as
55+
// little-endian u64
56+
// 23.. compressed LLVM bitcode
57+
58+
// This is the "magic number" expected at the beginning of a LLVM bytecode
59+
// object in an rlib.
60+
pub static RLIB_BYTECODE_OBJECT_MAGIC: &'static [u8] = b"RUST_OBJECT";
61+
62+
// The version number this compiler will write to bytecode objects in rlibs
63+
pub static RLIB_BYTECODE_OBJECT_VERSION: u32 = 1;
64+
65+
// The offset in bytes the bytecode object format version number can be found at
66+
pub static RLIB_BYTECODE_OBJECT_VERSION_OFFSET: uint = 11;
67+
68+
// The offset in bytes the size of the compressed bytecode can be found at in
69+
// format version 1
70+
pub static RLIB_BYTECODE_OBJECT_V1_DATASIZE_OFFSET: uint =
71+
RLIB_BYTECODE_OBJECT_VERSION_OFFSET + 4;
72+
73+
// The offset in bytes the compressed LLVM bytecode can be found at in format
74+
// version 1
75+
pub static RLIB_BYTECODE_OBJECT_V1_DATA_OFFSET: uint =
76+
RLIB_BYTECODE_OBJECT_V1_DATASIZE_OFFSET + 8;
77+
78+
4879
#[deriving(Clone, PartialEq, PartialOrd, Ord, Eq)]
4980
pub enum OutputType {
5081
OutputTypeBitcode,
@@ -1103,28 +1134,44 @@ fn link_rlib<'a>(sess: &'a Session,
11031134
// is never exactly 16 bytes long by adding a 16 byte extension to
11041135
// it. This is to work around a bug in LLDB that would cause it to
11051136
// crash if the name of a file in an archive was exactly 16 bytes.
1106-
let bc = obj_filename.with_extension("bc");
1107-
let bc_deflated = obj_filename.with_extension("bytecode.deflate");
1108-
match fs::File::open(&bc).read_to_end().and_then(|data| {
1109-
fs::File::create(&bc_deflated)
1110-
.write(match flate::deflate_bytes(data.as_slice()) {
1111-
Some(compressed) => compressed,
1112-
None => sess.fatal("failed to compress bytecode")
1113-
}.as_slice())
1114-
}) {
1137+
let bc_filename = obj_filename.with_extension("bc");
1138+
let bc_deflated_filename = obj_filename.with_extension("bytecode.deflate");
1139+
1140+
let bc_data = match fs::File::open(&bc_filename).read_to_end() {
1141+
Ok(buffer) => buffer,
1142+
Err(e) => sess.fatal(format!("failed to read bytecode: {}",
1143+
e).as_slice())
1144+
};
1145+
1146+
let bc_data_deflated = match flate::deflate_bytes(bc_data.as_slice()) {
1147+
Some(compressed) => compressed,
1148+
None => sess.fatal(format!("failed to compress bytecode from {}",
1149+
bc_filename.display()).as_slice())
1150+
};
1151+
1152+
let mut bc_file_deflated = match fs::File::create(&bc_deflated_filename) {
1153+
Ok(file) => file,
1154+
Err(e) => {
1155+
sess.fatal(format!("failed to create compressed bytecode \
1156+
file: {}", e).as_slice())
1157+
}
1158+
};
1159+
1160+
match write_rlib_bytecode_object_v1(&mut bc_file_deflated,
1161+
bc_data_deflated.as_slice()) {
11151162
Ok(()) => {}
11161163
Err(e) => {
11171164
sess.err(format!("failed to write compressed bytecode: \
1118-
{}",
1119-
e).as_slice());
1165+
{}", e).as_slice());
11201166
sess.abort_if_errors()
11211167
}
1122-
}
1123-
ab.add_file(&bc_deflated).unwrap();
1124-
remove(sess, &bc_deflated);
1168+
};
1169+
1170+
ab.add_file(&bc_deflated_filename).unwrap();
1171+
remove(sess, &bc_deflated_filename);
11251172
if !sess.opts.cg.save_temps &&
11261173
!sess.opts.output_types.contains(&OutputTypeBitcode) {
1127-
remove(sess, &bc);
1174+
remove(sess, &bc_filename);
11281175
}
11291176
}
11301177

@@ -1134,6 +1181,32 @@ fn link_rlib<'a>(sess: &'a Session,
11341181
ab
11351182
}
11361183

1184+
fn write_rlib_bytecode_object_v1<T: Writer>(writer: &mut T,
1185+
bc_data_deflated: &[u8])
1186+
-> ::std::io::IoResult<()> {
1187+
let bc_data_deflated_size: u64 = bc_data_deflated.as_slice().len() as u64;
1188+
1189+
try! { writer.write(RLIB_BYTECODE_OBJECT_MAGIC) };
1190+
try! { writer.write_le_u32(1) };
1191+
try! { writer.write_le_u64(bc_data_deflated_size) };
1192+
try! { writer.write(bc_data_deflated.as_slice()) };
1193+
1194+
let number_of_bytes_written_so_far =
1195+
RLIB_BYTECODE_OBJECT_MAGIC.len() + // magic id
1196+
mem::size_of_val(&RLIB_BYTECODE_OBJECT_VERSION) + // version
1197+
mem::size_of_val(&bc_data_deflated_size) + // data size field
1198+
bc_data_deflated_size as uint; // actual data
1199+
1200+
// If the number of bytes written to the object so far is odd, add a
1201+
// padding byte to make it even. This works around a crash bug in LLDB
1202+
// (see issue #15950)
1203+
if number_of_bytes_written_so_far % 2 == 1 {
1204+
try! { writer.write_u8(0) };
1205+
}
1206+
1207+
return Ok(());
1208+
}
1209+
11371210
// Create a static archive
11381211
//
11391212
// This is essentially the same thing as an rlib, but it also involves adding

trunk/src/librustc/back/lto.rs

Lines changed: 80 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ use util::common::time;
2020
use libc;
2121
use flate;
2222

23+
use std::mem;
24+
2325
pub fn run(sess: &session::Session, llmod: ModuleRef,
2426
tm: TargetMachineRef, reachable: &[String]) {
2527
if sess.opts.cg.prefer_dynamic {
@@ -57,36 +59,66 @@ pub fn run(sess: &session::Session, llmod: ModuleRef,
5759
let file = path.filename_str().unwrap();
5860
let file = file.slice(3, file.len() - 5); // chop off lib/.rlib
5961
debug!("reading {}", file);
60-
let bc = time(sess.time_passes(),
61-
format!("read {}.bytecode.deflate", name).as_slice(),
62-
(),
63-
|_| {
64-
archive.read(format!("{}.bytecode.deflate",
65-
file).as_slice())
66-
});
67-
let bc = bc.expect("missing compressed bytecode in archive!");
68-
let bc = time(sess.time_passes(),
69-
format!("inflate {}.bc", file).as_slice(),
70-
(),
71-
|_| {
72-
match flate::inflate_bytes(bc) {
73-
Some(bc) => bc,
74-
None => {
75-
sess.fatal(format!("failed to decompress \
76-
bc of `{}`",
77-
name).as_slice())
78-
}
79-
}
80-
});
81-
let ptr = bc.as_slice().as_ptr();
62+
let bc_encoded = time(sess.time_passes(),
63+
format!("read {}.bytecode.deflate", name).as_slice(),
64+
(),
65+
|_| {
66+
archive.read(format!("{}.bytecode.deflate",
67+
file).as_slice())
68+
});
69+
let bc_encoded = bc_encoded.expect("missing compressed bytecode in archive!");
70+
let bc_extractor = if is_versioned_bytecode_format(bc_encoded) {
71+
|_| {
72+
// Read the version
73+
let version = extract_bytecode_format_version(bc_encoded);
74+
75+
if version == 1 {
76+
// The only version existing so far
77+
let data_size = extract_compressed_bytecode_size_v1(bc_encoded);
78+
let compressed_data = bc_encoded.slice(
79+
link::RLIB_BYTECODE_OBJECT_V1_DATA_OFFSET,
80+
link::RLIB_BYTECODE_OBJECT_V1_DATA_OFFSET + data_size as uint);
81+
82+
match flate::inflate_bytes(compressed_data) {
83+
Some(inflated) => inflated,
84+
None => {
85+
sess.fatal(format!("failed to decompress bc of `{}`",
86+
name).as_slice())
87+
}
88+
}
89+
} else {
90+
sess.fatal(format!("Unsupported bytecode format version {}",
91+
version).as_slice())
92+
}
93+
}
94+
} else {
95+
// the object must be in the old, pre-versioning format, so simply
96+
// inflate everything and let LLVM decide if it can make sense of it
97+
|_| {
98+
match flate::inflate_bytes(bc_encoded) {
99+
Some(bc) => bc,
100+
None => {
101+
sess.fatal(format!("failed to decompress bc of `{}`",
102+
name).as_slice())
103+
}
104+
}
105+
}
106+
};
107+
108+
let bc_decoded = time(sess.time_passes(),
109+
format!("decode {}.bc", file).as_slice(),
110+
(),
111+
bc_extractor);
112+
113+
let ptr = bc_decoded.as_slice().as_ptr();
82114
debug!("linking {}", name);
83115
time(sess.time_passes(),
84116
format!("ll link {}", name).as_slice(),
85117
(),
86118
|()| unsafe {
87119
if !llvm::LLVMRustLinkInExternalBitcode(llmod,
88120
ptr as *const libc::c_char,
89-
bc.len() as libc::size_t) {
121+
bc_decoded.len() as libc::size_t) {
90122
link::llvm_err(sess,
91123
format!("failed to load bc of `{}`",
92124
name.as_slice()));
@@ -137,3 +169,28 @@ pub fn run(sess: &session::Session, llmod: ModuleRef,
137169
}
138170
debug!("lto done");
139171
}
172+
173+
fn is_versioned_bytecode_format(bc: &[u8]) -> bool {
174+
let magic_id_byte_count = link::RLIB_BYTECODE_OBJECT_MAGIC.len();
175+
return bc.len() > magic_id_byte_count &&
176+
bc.slice(0, magic_id_byte_count) == link::RLIB_BYTECODE_OBJECT_MAGIC;
177+
}
178+
179+
fn extract_bytecode_format_version(bc: &[u8]) -> u32 {
180+
return read_from_le_bytes::<u32>(bc, link::RLIB_BYTECODE_OBJECT_VERSION_OFFSET);
181+
}
182+
183+
fn extract_compressed_bytecode_size_v1(bc: &[u8]) -> u64 {
184+
return read_from_le_bytes::<u64>(bc, link::RLIB_BYTECODE_OBJECT_V1_DATASIZE_OFFSET);
185+
}
186+
187+
fn read_from_le_bytes<T: Int>(bytes: &[u8], position_in_bytes: uint) -> T {
188+
let byte_data = bytes.slice(position_in_bytes,
189+
position_in_bytes + mem::size_of::<T>());
190+
let data = unsafe {
191+
*(byte_data.as_ptr() as *const T)
192+
};
193+
194+
Int::from_le(data)
195+
}
196+

0 commit comments

Comments
 (0)