Get compiling on Rust 1.0 beta

This commit is contained in:
Carl Lerche
2015-04-03 23:45:34 -07:00
parent 635274752b
commit 29e5dc72bb
7 changed files with 66 additions and 93 deletions
+16 -23
View File
@@ -1,5 +1,5 @@
use std::{mem, ptr}; use std::{mem, ptr};
use std::rt::heap; use std::ops::DerefMut;
use std::sync::atomic::{AtomicUsize, Ordering}; use std::sync::atomic::{AtomicUsize, Ordering};
use std::usize; use std::usize;
@@ -52,13 +52,9 @@ impl MemRef {
} }
pub fn bytes(&self) -> &[u8] { pub fn bytes(&self) -> &[u8] {
use std::raw::Slice; use std::slice;
unsafe { unsafe {
mem::transmute(Slice { slice::from_raw_parts(self.ptr(), self.mem().len)
data: self.ptr(),
len: self.mem().len,
})
} }
} }
@@ -139,33 +135,30 @@ impl Heap {
return MemRef::none(); return MemRef::none();
} }
let alloc_len = len + mem::size_of::<Mem>(); let alloc_len = len +
mem::size_of::<Mem>() +
mem::size_of::<Vec<u8>>();
unsafe { unsafe {
// Attempt to allocate the memory let mut vec: Vec<u8> = Vec::with_capacity(alloc_len);
let ptr: *mut Mem = mem::transmute( vec.set_len(alloc_len);
heap::allocate(alloc_len, mem::min_align_of::<u8>()));
// If failed, return None let ptr = vec.deref_mut().as_mut_ptr();
if ptr.is_null() {
return MemRef::none();
}
// Write the mem header ptr::write(ptr as *mut Vec<u8>, vec);
ptr::write(ptr, Mem::new(len, mem::transmute(self as &Allocator)));
let ptr = ptr.offset(mem::size_of::<Vec<u8>>() as isize);
ptr::write(ptr as *mut Mem, Mem::new(len, mem::transmute(self as &Allocator)));
// Return the info // Return the info
MemRef::new(ptr) MemRef::new(ptr as *mut Mem)
} }
} }
pub fn deallocate(&self, mem: *mut Mem) { pub fn deallocate(&self, mem: *mut Mem) {
unsafe { unsafe {
let m: &Mem = mem::transmute(mem); let ptr = mem as *mut u8;
let _ = ptr::read(ptr.offset(-(mem::size_of::<Vec<u8>>() as isize)) as *const Vec<u8>);
heap::deallocate(
mem as *mut u8, m.len + mem::size_of::<Mem>(),
mem::min_align_of::<u8>())
} }
} }
} }
+7 -3
View File
@@ -135,8 +135,7 @@ impl SmallByteStr {
} }
pub fn from_slice(bytes: &[u8]) -> Option<SmallByteStr> { pub fn from_slice(bytes: &[u8]) -> Option<SmallByteStr> {
use std::mem; use std::{mem, ptr};
use std::slice::bytes;
if bytes.len() > MAX_LEN { if bytes.len() > MAX_LEN {
return None; return None;
@@ -148,7 +147,12 @@ impl SmallByteStr {
}; };
// Copy the memory // Copy the memory
bytes::copy_memory(bytes, &mut ret.bytes); unsafe {
ptr::copy_nonoverlapping(
bytes.as_ptr(),
ret.bytes.as_mut_ptr(),
bytes.len());
}
Some(ret) Some(ret)
} }
+19 -14
View File
@@ -2,15 +2,12 @@ use {ByteBuf, SmallByteStr};
use traits::{Buf, ByteStr, ToBytes}; use traits::{Buf, ByteStr, ToBytes};
use std::{fmt, mem, ops, ptr}; use std::{fmt, mem, ops, ptr};
use std::any::{Any, TypeId}; use std::any::{Any, TypeId};
use std::marker::Reflect;
use std::raw::TraitObject;
use core::nonzero::NonZero;
const INLINE: usize = 1; const INLINE: usize = 1;
/// A specialized `ByteStr` box. /// A specialized `ByteStr` box.
pub struct Bytes { pub struct Bytes {
vtable: NonZero<usize>, vtable: usize,
data: *mut (), data: *mut (),
} }
@@ -40,7 +37,7 @@ impl Bytes {
mem::forget(bytes); mem::forget(bytes);
Bytes { Bytes {
vtable: NonZero::new(vtable as usize | INLINE), vtable: vtable as usize | INLINE,
data: data, data: data,
} }
} else { } else {
@@ -48,7 +45,7 @@ impl Bytes {
let obj: TraitObject = mem::transmute(obj); let obj: TraitObject = mem::transmute(obj);
Bytes { Bytes {
vtable: NonZero::new(obj.vtable as usize), vtable: obj.vtable as usize,
data: obj.data, data: obj.data,
} }
} }
@@ -77,7 +74,7 @@ impl Bytes {
/// If the underlying `ByteStr` is of type `B`, returns the unwraped value, /// If the underlying `ByteStr` is of type `B`, returns the unwraped value,
/// otherwise, returns the original `Bytes` as `Err`. /// otherwise, returns the original `Bytes` as `Err`.
pub fn try_unwrap<B: ByteStr + Reflect>(self) -> Result<B, Bytes> { pub fn try_unwrap<B: ByteStr>(self) -> Result<B, Bytes> {
if TypeId::of::<B>() == self.obj().get_type_id() { if TypeId::of::<B>() == self.obj().get_type_id() {
unsafe { unsafe {
// Underlying ByteStr value is of the correct type. Unwrap it // Underlying ByteStr value is of the correct type. Unwrap it
@@ -103,12 +100,12 @@ impl Bytes {
let obj = if self.is_inline() { let obj = if self.is_inline() {
TraitObject { TraitObject {
data: mem::transmute(&self.data), data: mem::transmute(&self.data),
vtable: mem::transmute(*self.vtable - 1), vtable: mem::transmute(self.vtable - 1),
} }
} else { } else {
TraitObject { TraitObject {
data: self.data, data: self.data,
vtable: mem::transmute(*self.vtable), vtable: mem::transmute(self.vtable),
} }
}; };
@@ -121,12 +118,12 @@ impl Bytes {
} }
fn is_inline(&self) -> bool { fn is_inline(&self) -> bool {
(*self.vtable & INLINE) == INLINE (self.vtable & INLINE) == INLINE
} }
} }
fn inline<B: ByteStr>() -> bool { fn inline<B: ByteStr>() -> bool {
mem::size_of::<B>() <= mem::size_of::<usize>() mem::size_of::<B>() <= 2 * mem::size_of::<usize>()
} }
impl ByteStr for Bytes { impl ByteStr for Bytes {
@@ -239,7 +236,7 @@ impl<B: ByteStr> ByteStrPriv for B {
} }
fn get_type_id(&self) -> TypeId { fn get_type_id(&self) -> TypeId {
Any::get_type_id(self) TypeId::of::<B>()
} }
fn index(&self, index: usize) -> &u8 { fn index(&self, index: usize) -> &u8 {
@@ -259,11 +256,19 @@ impl<B: ByteStr> ByteStrPriv for B {
} }
} }
// TODO: Figure out how to not depend on the memory layout of trait objects
// Blocked: rust-lang/rust#24050
struct TraitObject {
data: *mut (),
vtable: *mut (),
}
#[test] #[test]
pub fn test_size_of() { pub fn test_size_of() {
// TODO: One day, there shouldn't be a drop flag // TODO: One day, there shouldn't be a drop flag
let expect = mem::size_of::<usize>() * 3; let ptr_size = mem::size_of::<usize>();
let expect = ptr_size * 3;
assert_eq!(expect, mem::size_of::<Bytes>()); assert_eq!(expect, mem::size_of::<Bytes>());
assert_eq!(expect, mem::size_of::<Option<Bytes>>()); assert_eq!(expect + ptr_size, mem::size_of::<Option<Bytes>>());
} }
+2 -6
View File
@@ -1,8 +1,6 @@
#![crate_name = "bytes"] #![crate_name = "bytes"]
#![unstable] #![unstable]
#![feature(alloc, convert, core)]
pub use byte_buf::{ByteBuf, ROByteBuf, MutByteBuf}; pub use byte_buf::{ByteBuf, ROByteBuf, MutByteBuf};
pub use byte_str::{SeqByteStr, SmallByteStr, SmallByteStrBuf}; pub use byte_str::{SeqByteStr, SmallByteStr, SmallByteStrBuf};
pub use bytes::Bytes; pub use bytes::Bytes;
@@ -11,9 +9,7 @@ pub use rope::{Rope, RopeBuf};
pub use slice::{SliceBuf, MutSliceBuf}; pub use slice::{SliceBuf, MutSliceBuf};
use std::{cmp, fmt, io, ops, ptr, u32}; use std::{cmp, fmt, io, ops, ptr, u32};
use std::marker::Reflect; use std::any::Any;
extern crate core;
mod alloc; mod alloc;
mod byte_buf; mod byte_buf;
@@ -201,7 +197,7 @@ pub trait MutBufExt {
/// An immutable sequence of bytes. Operations will not mutate the original /// An immutable sequence of bytes. Operations will not mutate the original
/// value. Since only immutable access is permitted, operations do not require /// value. Since only immutable access is permitted, operations do not require
/// copying (though, sometimes copying will happen as an optimization). /// copying (though, sometimes copying will happen as an optimization).
pub trait ByteStr : Clone + Sized + Send + Sync + Reflect + ToBytes + ops::Index<usize, Output=u8> + 'static { pub trait ByteStr : Clone + Sized + Send + Sync + Any + ToBytes + ops::Index<usize, Output=u8> + 'static {
// Until HKT lands, the buf must be bound by 'static // Until HKT lands, the buf must be bound by 'static
type Buf: Buf+'static; type Buf: Buf+'static;
+15 -40
View File
@@ -1,16 +1,14 @@
use super::{Buf, MutBuf}; use {alloc, Buf, MutBuf};
use std::{cmp, fmt, mem, ptr, slice}; use std::{cmp, fmt, io, ptr};
use std::rt::heap;
use std::io;
/// Buf backed by a continous chunk of memory. Maintains a read cursor and a /// Buf backed by a continous chunk of memory. Maintains a read cursor and a
/// write cursor. When reads and writes reach the end of the allocated buffer, /// write cursor. When reads and writes reach the end of the allocated buffer,
/// wraps around to the start. /// wraps around to the start.
pub struct RingBuf { pub struct RingBuf {
ptr: *mut u8, // Pointer to the memory ptr: alloc::MemRef, // Pointer to the memory
cap: usize, // Capacity of the buffer cap: usize, // Capacity of the buffer
pos: usize, // Offset of read cursor pos: usize, // Offset of read cursor
len: usize // Number of bytes to read len: usize // Number of bytes to read
} }
// TODO: There are most likely many optimizations that can be made // TODO: There are most likely many optimizations that can be made
@@ -19,7 +17,7 @@ impl RingBuf {
// Handle the 0 length buffer case // Handle the 0 length buffer case
if capacity == 0 { if capacity == 0 {
return RingBuf { return RingBuf {
ptr: ptr::null_mut(), ptr: alloc::MemRef::none(),
cap: 0, cap: 0,
pos: 0, pos: 0,
len: 0 len: 0
@@ -29,11 +27,10 @@ impl RingBuf {
// Round to the next power of 2 for better alignment // Round to the next power of 2 for better alignment
capacity = capacity.next_power_of_two(); capacity = capacity.next_power_of_two();
// Allocate the memory let mem = alloc::HEAP.allocate(capacity as usize);
let ptr = unsafe { heap::allocate(capacity, mem::min_align_of::<u8>()) };
RingBuf { RingBuf {
ptr: ptr as *mut u8, ptr: mem,
cap: capacity, cap: capacity,
pos: 0, pos: 0,
len: 0 len: 0
@@ -75,18 +72,6 @@ impl RingBuf {
cnt = cmp::min(cnt, self.write_remaining()); cnt = cmp::min(cnt, self.write_remaining());
self.len += cnt; self.len += cnt;
} }
fn as_slice(&self) -> &[u8] {
unsafe {
slice::from_raw_parts(self.ptr as *const u8, self.cap)
}
}
fn as_mut_slice(&mut self) -> &mut [u8] {
unsafe {
slice::from_raw_parts_mut(self.ptr, self.cap)
}
}
} }
impl Clone for RingBuf { impl Clone for RingBuf {
@@ -102,12 +87,12 @@ impl Clone for RingBuf {
let to = self.pos + self.len; let to = self.pos + self.len;
if to > self.cap { if to > self.cap {
ptr::copy(self.ptr as *const u8, ret.ptr, to % self.cap); ptr::copy(self.ptr.ptr() as *const u8, ret.ptr.ptr(), to % self.cap);
} }
ptr::copy( ptr::copy(
self.ptr.offset(self.pos as isize) as *const u8, self.ptr.ptr().offset(self.pos as isize) as *const u8,
ret.ptr.offset(self.pos as isize), ret.ptr.ptr().offset(self.pos as isize),
cmp::min(self.len, self.cap - self.pos)); cmp::min(self.len, self.cap - self.pos));
} }
@@ -124,16 +109,6 @@ impl fmt::Debug for RingBuf {
} }
} }
impl Drop for RingBuf {
fn drop(&mut self) {
if self.cap > 0 {
unsafe {
heap::deallocate(self.ptr, self.cap, mem::min_align_of::<u8>())
}
}
}
}
impl Buf for RingBuf { impl Buf for RingBuf {
fn remaining(&self) -> usize { fn remaining(&self) -> usize {
@@ -147,7 +122,7 @@ impl Buf for RingBuf {
to = self.cap to = self.cap
} }
&self.as_slice()[self.pos .. to] &self.ptr.bytes()[self.pos .. to]
} }
fn advance(&mut self, cnt: usize) { fn advance(&mut self, cnt: usize) {
@@ -167,7 +142,7 @@ impl MutBuf for RingBuf {
fn mut_bytes(&mut self) -> &mut [u8] { fn mut_bytes(&mut self) -> &mut [u8] {
if self.cap == 0 { if self.cap == 0 {
return self.as_mut_slice(); return self.ptr.bytes_mut();
} }
let mut from; let mut from;
let mut to; let mut to;
@@ -181,7 +156,7 @@ impl MutBuf for RingBuf {
to = self.cap; to = self.cap;
} }
&mut self.as_mut_slice()[from..to] &mut self.ptr.bytes_mut()[from..to]
} }
} }
-2
View File
@@ -1,5 +1,3 @@
#![feature(core)]
use rand::random; use rand::random;
extern crate bytes; extern crate bytes;
+7 -5
View File
@@ -20,8 +20,7 @@ struct Chunked {
impl io::Read for Chunked { impl io::Read for Chunked {
fn read(&mut self, dst: &mut [u8]) -> io::Result<usize> { fn read(&mut self, dst: &mut [u8]) -> io::Result<usize> {
use std::cmp; use std::{cmp, ptr};
use std::slice::bytes;
if self.chunks.is_empty() { if self.chunks.is_empty() {
return Ok(0); return Ok(0);
@@ -30,9 +29,12 @@ impl io::Read for Chunked {
let src = self.chunks[0]; let src = self.chunks[0];
let len = cmp::min(src.len(), dst.len()); let len = cmp::min(src.len(), dst.len());
bytes::copy_memory( unsafe {
&src[..len], ptr::copy_nonoverlapping(
&mut dst[..len]); src[..len].as_ptr(),
dst[..len].as_mut_ptr(),
len);
}
if len < src.len() { if len < src.len() {
self.chunks[0] = &src[len..]; self.chunks[0] = &src[len..];