libcore: Remove more mutable fields from comm

This commit is contained in:
Patrick Walton 2013-05-03 17:37:08 -07:00
parent 8919f32f83
commit d12d25534b
4 changed files with 114 additions and 73 deletions

View File

@ -234,8 +234,9 @@ impl<T: Owned> Selectable for Port<T> {
}
/// Treat many ports as one.
#[unsafe_mut_field(ports)]
pub struct PortSet<T> {
mut ports: ~[Port<T>],
ports: ~[Port<T>],
}
pub impl<T: Owned> PortSet<T> {
@ -246,7 +247,10 @@ pub impl<T: Owned> PortSet<T> {
}
fn add(&self, port: Port<T>) {
self.ports.push(port)
unsafe {
let self_ports = transmute_mut(&self.ports);
self_ports.push(port)
}
}
fn chan(&self) -> Chan<T> {
@ -258,25 +262,28 @@ pub impl<T: Owned> PortSet<T> {
impl<T:Owned> GenericPort<T> for PortSet<T> {
fn try_recv(&self) -> Option<T> {
let mut result = None;
// we have to swap the ports array so we aren't borrowing
// aliasable mutable memory.
let mut ports = ~[];
ports <-> self.ports;
while result.is_none() && ports.len() > 0 {
let i = wait_many(ports);
match ports[i].try_recv() {
Some(m) => {
result = Some(m);
}
None => {
// Remove this port.
let _ = ports.swap_remove(i);
unsafe {
let mut self_ports = transmute_mut(&self.ports);
let mut result = None;
// we have to swap the ports array so we aren't borrowing
// aliasable mutable memory.
let mut ports = ~[];
ports <-> *self_ports;
while result.is_none() && ports.len() > 0 {
let i = wait_many(ports);
match ports[i].try_recv() {
Some(m) => {
result = Some(m);
}
None => {
// Remove this port.
let _ = ports.swap_remove(i);
}
}
}
ports <-> *self_ports;
result
}
ports <-> self.ports;
result
}
fn recv(&self) -> T {
self.try_recv().expect("port_set: endpoints closed")
@ -288,10 +295,9 @@ impl<T: Owned> Peekable<T> for PortSet<T> {
// It'd be nice to use self.port.each, but that version isn't
// pure.
for uint::range(0, vec::uniq_len(&const self.ports)) |i| {
// XXX: Botch pending demuting.
unsafe {
let port: &Port<T> = cast::transmute(&mut self.ports[i]);
if port.peek() { return true }
let port: &Port<T> = &self.ports[i];
if port.peek() {
return true;
}
}
false

View File

@ -983,36 +983,50 @@ pub fn file_reader(path: &Path) -> Result<@Reader, ~str> {
// Byte readers
pub struct BytesReader<'self> {
bytes: &'self [u8],
mut pos: uint
pos: @mut uint
}
impl<'self> Reader for BytesReader<'self> {
fn read(&self, bytes: &mut [u8], len: uint) -> uint {
let count = uint::min(len, self.bytes.len() - self.pos);
let count = uint::min(len, self.bytes.len() - *self.pos);
let view = vec::slice(self.bytes, self.pos, self.bytes.len());
let view = vec::slice(self.bytes, *self.pos, self.bytes.len());
vec::bytes::copy_memory(bytes, view, count);
self.pos += count;
*self.pos += count;
count
}
fn read_byte(&self) -> int {
if self.pos == self.bytes.len() { return -1; }
let b = self.bytes[self.pos];
self.pos += 1u;
return b as int;
if *self.pos == self.bytes.len() {
return -1;
}
let b = self.bytes[*self.pos];
*self.pos += 1u;
b as int
}
fn eof(&self) -> bool { self.pos == self.bytes.len() }
fn eof(&self) -> bool {
*self.pos == self.bytes.len()
}
fn seek(&self, offset: int, whence: SeekStyle) {
let pos = self.pos;
self.pos = seek_in_buf(offset, pos, self.bytes.len(), whence);
let pos = *self.pos;
*self.pos = seek_in_buf(offset, pos, self.bytes.len(), whence);
}
fn tell(&self) -> uint {
*self.pos
}
fn tell(&self) -> uint { self.pos }
}
pub fn with_bytes_reader<t>(bytes: &[u8], f: &fn(@Reader) -> t) -> t {
f(@BytesReader { bytes: bytes, pos: 0u } as @Reader)
pub fn with_bytes_reader<T>(bytes: &[u8], f: &fn(@Reader) -> T) -> T {
f(@BytesReader {
bytes: bytes,
pos: @mut 0
} as @Reader)
}
pub fn with_str_reader<T>(s: &str, f: &fn(@Reader) -> T) -> T {
@ -1498,49 +1512,67 @@ pub fn buffered_file_writer(path: &Path) -> Result<@Writer, ~str> {
pub fn stdout() -> @Writer { fd_writer(libc::STDOUT_FILENO as c_int, false) }
pub fn stderr() -> @Writer { fd_writer(libc::STDERR_FILENO as c_int, false) }
pub fn print(s: &str) { stdout().write_str(s); }
pub fn println(s: &str) { stdout().write_line(s); }
pub fn print(s: &str) {
stdout().write_str(s);
}
pub fn println(s: &str) {
stdout().write_line(s);
}
pub struct BytesWriter {
mut bytes: ~[u8],
mut pos: uint,
bytes: @mut ~[u8],
pos: @mut uint,
}
impl Writer for BytesWriter {
fn write(&self, v: &[u8]) {
let v_len = v.len();
let bytes_len = vec::uniq_len(&const self.bytes);
let bytes_len = vec::uniq_len(&const *self.bytes);
let count = uint::max(bytes_len, self.pos + v_len);
vec::reserve(&mut self.bytes, count);
let count = uint::max(bytes_len, *self.pos + v_len);
vec::reserve(&mut *self.bytes, count);
unsafe {
vec::raw::set_len(&mut self.bytes, count);
let view = vec::mut_slice(self.bytes, self.pos, count);
vec::raw::set_len(&mut *self.bytes, count);
let view = vec::mut_slice(*self.bytes, *self.pos, count);
vec::bytes::copy_memory(view, v, v_len);
}
self.pos += v_len;
*self.pos += v_len;
}
fn seek(&self, offset: int, whence: SeekStyle) {
let pos = self.pos;
let len = vec::uniq_len(&const self.bytes);
self.pos = seek_in_buf(offset, pos, len, whence);
let pos = *self.pos;
let len = vec::uniq_len(&const *self.bytes);
*self.pos = seek_in_buf(offset, pos, len, whence);
}
fn tell(&self) -> uint {
*self.pos
}
fn flush(&self) -> int {
0
}
fn get_type(&self) -> WriterType {
File
}
fn tell(&self) -> uint { self.pos }
fn flush(&self) -> int { 0 }
fn get_type(&self) -> WriterType { File }
}
pub fn BytesWriter() -> BytesWriter {
BytesWriter { bytes: ~[], mut pos: 0u }
BytesWriter {
bytes: @mut ~[],
pos: @mut 0
}
}
pub fn with_bytes_writer(f: &fn(@Writer)) -> ~[u8] {
let wr = @BytesWriter();
f(wr as @Writer);
let @BytesWriter{bytes, _} = wr;
return bytes;
let @BytesWriter { bytes, _ } = wr;
copy *bytes
}
pub fn with_str_writer(f: &fn(@Writer)) -> ~str {
@ -1550,7 +1582,9 @@ pub fn with_str_writer(f: &fn(@Writer)) -> ~str {
v.push(0);
assert!(str::is_utf8(v));
unsafe { ::cast::transmute(v) }
unsafe {
::cast::transmute(v)
}
}
// Utility functions

View File

@ -1372,41 +1372,40 @@ pub fn encode_metadata(parms: EncodeParams, crate: &crate) -> ~[u8] {
encode_hash(&mut ebml_w, ecx.link_meta.extras_hash);
let mut i = wr.pos;
let mut i = *wr.pos;
let crate_attrs = synthesize_crate_attrs(ecx, crate);
encode_attributes(&mut ebml_w, crate_attrs);
ecx.stats.attr_bytes = wr.pos - i;
ecx.stats.attr_bytes = *wr.pos - i;
i = wr.pos;
i = *wr.pos;
encode_crate_deps(ecx, &mut ebml_w, ecx.cstore);
ecx.stats.dep_bytes = wr.pos - i;
ecx.stats.dep_bytes = *wr.pos - i;
// Encode the language items.
i = wr.pos;
i = *wr.pos;
encode_lang_items(ecx, &mut ebml_w);
ecx.stats.lang_item_bytes = wr.pos - i;
ecx.stats.lang_item_bytes = *wr.pos - i;
// Encode the link args.
i = wr.pos;
i = *wr.pos;
encode_link_args(ecx, &mut ebml_w);
ecx.stats.link_args_bytes = wr.pos - i;
ecx.stats.link_args_bytes = *wr.pos - i;
// Encode and index the items.
ebml_w.start_tag(tag_items);
i = wr.pos;
i = *wr.pos;
let items_index = encode_info_for_items(ecx, &mut ebml_w, crate);
ecx.stats.item_bytes = wr.pos - i;
ecx.stats.item_bytes = *wr.pos - i;
i = wr.pos;
i = *wr.pos;
let items_buckets = create_index(items_index);
encode_index(&mut ebml_w, items_buckets, write_int);
ecx.stats.index_bytes = wr.pos - i;
ecx.stats.index_bytes = *wr.pos - i;
ebml_w.end_tag();
ecx.stats.total_bytes = wr.pos;
ecx.stats.total_bytes = *wr.pos;
if (tcx.sess.meta_stats()) {
do wr.bytes.each |e| {
if *e == 0 {
ecx.stats.zero_bytes += 1;
@ -1438,9 +1437,11 @@ pub fn encode_metadata(parms: EncodeParams, crate: &crate) -> ~[u8] {
//
// vec::from_slice(metadata_encoding_version) +
let writer_bytes: &mut ~[u8] = wr.bytes;
(do str::as_bytes(&~"rust\x00\x00\x00\x01") |bytes| {
vec::slice(*bytes, 0, 8).to_vec()
}) + flate::deflate_bytes(wr.bytes)
}) + flate::deflate_bytes(*writer_bytes)
}
// Get the encoded string for a type

View File

@ -29,13 +29,13 @@ pub impl BufReader {
// I can't get the borrowing to work correctly
let bytes_reader = BytesReader {
bytes: ::core::util::id::<&[u8]>(self.buf),
pos: *self.pos
pos: @mut *self.pos
};
let res = f(&bytes_reader);
// FIXME #4429: This isn't correct if f fails
*self.pos = bytes_reader.pos;
*self.pos = *bytes_reader.pos;
return res;
}