提交 5aaaca0c 编写于 作者: A Alex Crichton

Consolidate raw representations of rust values

This moves the raw struct layout of closures, vectors, boxes, and strings into a
new `unstable::raw` module. This is meant to be a centralized location to find
information for the layout of these values.

As safe method, `repr`, is provided to convert a rust value to its raw
representation. Unsafe methods to convert back are not provided because they are
rarely used and too numerous to write an implementation for each (not much of a
common pattern).
上级 7fd23e4f
......@@ -10,13 +10,13 @@
//! Managed vectors
use cast::transmute;
use clone::Clone;
use container::Container;
use iterator::IteratorUtil;
use option::Option;
use sys;
use uint;
use unstable::raw::Repr;
use vec::{ImmutableVector, OwnedVector};
/// Code for dealing with @-vectors. This is pretty incomplete, and
......@@ -26,8 +26,8 @@
#[inline]
pub fn capacity<T>(v: @[T]) -> uint {
unsafe {
let repr: **raw::VecRepr = transmute(&v);
(**repr).unboxed.alloc / sys::size_of::<T>()
let box = v.repr();
(*box).data.alloc / sys::size_of::<T>()
}
}
......@@ -45,10 +45,10 @@ pub fn capacity<T>(v: @[T]) -> uint {
*/
#[inline]
pub fn build_sized<A>(size: uint, builder: &fn(push: &fn(v: A))) -> @[A] {
let mut vec: @[A] = @[];
let mut vec = @[];
unsafe { raw::reserve(&mut vec, size); }
builder(|x| unsafe { raw::push(&mut vec, x) });
return unsafe { transmute(vec) };
vec
}
/**
......@@ -151,7 +151,7 @@ pub fn to_managed_consume<T>(v: ~[T]) -> @[T] {
for v.consume_iter().advance |x| {
raw::push(&mut av, x);
}
transmute(av)
av
}
}
......@@ -195,13 +195,9 @@ pub mod raw {
use ptr;
use sys;
use uint;
use unstable::intrinsics;
use unstable::intrinsics::{move_val_init, TyDesc};
use vec;
use vec::UnboxedVecRepr;
pub type VecRepr = vec::raw::VecRepr;
pub type SliceRepr = vec::raw::SliceRepr;
use unstable::intrinsics;
use unstable::raw::{Box, Vec};
/**
* Sets the length of a vector
......@@ -211,9 +207,9 @@ pub mod raw {
* the vector is actually the specified size.
*/
#[inline]
pub unsafe fn set_len<T>(v: @[T], new_len: uint) {
let repr: **mut VecRepr = transmute(&v);
(**repr).unboxed.fill = new_len * sys::size_of::<T>();
pub unsafe fn set_len<T>(v: &mut @[T], new_len: uint) {
let repr: *mut Box<Vec<T>> = cast::transmute_copy(v);
(*repr).data.fill = new_len * sys::size_of::<T>();
}
/**
......@@ -221,9 +217,11 @@ pub unsafe fn set_len<T>(v: @[T], new_len: uint) {
*/
#[inline]
pub unsafe fn push<T>(v: &mut @[T], initval: T) {
let repr: **VecRepr = transmute_copy(&v);
let fill = (**repr).unboxed.fill;
if (**repr).unboxed.alloc > fill {
let full = {
let repr: *Box<Vec<T>> = cast::transmute_copy(v);
(*repr).data.alloc > (*repr).data.fill
};
if full {
push_fast(v, initval);
} else {
push_slow(v, initval);
......@@ -232,16 +230,15 @@ pub unsafe fn push<T>(v: &mut @[T], initval: T) {
#[inline] // really pretty please
unsafe fn push_fast<T>(v: &mut @[T], initval: T) {
let repr: **mut VecRepr = ::cast::transmute(v);
let fill = (**repr).unboxed.fill;
(**repr).unboxed.fill += sys::size_of::<T>();
let p = &((**repr).unboxed.data);
let p = ptr::offset(p, fill) as *mut T;
let repr: *mut Box<Vec<T>> = cast::transmute_copy(v);
let amt = v.len();
(*repr).data.fill += sys::size_of::<T>();
let p = ptr::offset(&(*repr).data.data as *T, amt) as *mut T;
move_val_init(&mut(*p), initval);
}
unsafe fn push_slow<T>(v: &mut @[T], initval: T) {
reserve_at_least(&mut *v, v.len() + 1u);
reserve_at_least(v, v.len() + 1u);
push_fast(v, initval);
}
......@@ -259,7 +256,7 @@ unsafe fn push_slow<T>(v: &mut @[T], initval: T) {
pub unsafe fn reserve<T>(v: &mut @[T], n: uint) {
// Only make the (slow) call into the runtime if we have to
if capacity(*v) < n {
let ptr: *mut *mut VecRepr = transmute(v);
let ptr: *mut *mut Box<Vec<()>> = transmute(v);
let ty = intrinsics::get_tydesc::<T>();
// XXX transmute shouldn't be necessary
let ty = cast::transmute(ty);
......@@ -269,16 +266,14 @@ pub unsafe fn reserve<T>(v: &mut @[T], n: uint) {
// Implementation detail. Shouldn't be public
#[allow(missing_doc)]
pub fn reserve_raw(ty: *TyDesc, ptr: *mut *mut VecRepr, n: uint) {
pub fn reserve_raw(ty: *TyDesc, ptr: *mut *mut Box<Vec<()>>, n: uint) {
unsafe {
let size_in_bytes = n * (*ty).size;
if size_in_bytes > (**ptr).unboxed.alloc {
let total_size = size_in_bytes + sys::size_of::<UnboxedVecRepr>();
// XXX: UnboxedVecRepr has an extra u8 at the end
let total_size = total_size - sys::size_of::<u8>();
(*ptr) = local_realloc(*ptr as *(), total_size) as *mut VecRepr;
(**ptr).unboxed.alloc = size_in_bytes;
if size_in_bytes > (**ptr).data.alloc {
let total_size = size_in_bytes + sys::size_of::<Vec<()>>();
(*ptr) = local_realloc(*ptr as *(), total_size) as *mut Box<Vec<()>>;
(**ptr).data.alloc = size_in_bytes;
}
}
......
......@@ -133,6 +133,7 @@ pub unsafe fn copy_lifetime_vec<'a,S,T>(_ptr: &'a [S], ptr: &T) -> &'a T {
#[cfg(test)]
mod tests {
use cast::{bump_box_refcount, transmute};
use unstable::raw;
#[test]
fn test_transmute_copy() {
......@@ -156,10 +157,9 @@ fn test_bump_box_refcount() {
#[test]
fn test_transmute() {
use managed::raw::BoxRepr;
unsafe {
let x = @100u8;
let x: *BoxRepr = transmute(x);
let x: *raw::Box<u8> = transmute(x);
assert!((*x).data == 100);
let _x: @int = transmute(x);
}
......
......@@ -12,8 +12,8 @@
use libc::c_void;
use ptr::{mut_null};
use repr::BoxRepr;
use unstable::intrinsics::TyDesc;
use unstable::raw;
type DropGlue<'self> = &'self fn(**TyDesc, *c_void);
......@@ -30,14 +30,13 @@ struct AnnihilateStats {
}
unsafe fn each_live_alloc(read_next_before: bool,
f: &fn(box: *mut BoxRepr, uniq: bool) -> bool) -> bool {
f: &fn(box: *mut raw::Box<()>, uniq: bool) -> bool) -> bool {
//! Walks the internal list of allocations
use managed;
use rt::local_heap;
let box = local_heap::live_allocs();
let mut box: *mut BoxRepr = transmute(box);
let mut box = local_heap::live_allocs();
while box != mut_null() {
let next_before = (*box).next;
let uniq = (*box).ref_count == managed::RC_MANAGED_UNIQUE;
......@@ -100,7 +99,7 @@ pub unsafe fn annihilate() {
if uniq {
stats.n_unique_boxes += 1;
} else {
(*box).header.ref_count = managed::raw::RC_IMMORTAL;
(*box).ref_count = managed::RC_IMMORTAL;
}
}
......@@ -126,9 +125,9 @@ pub unsafe fn annihilate() {
for each_live_alloc(true) |box, uniq| {
if !uniq {
stats.n_bytes_freed +=
(*((*box).header.type_desc)).size
+ sys::size_of::<BoxRepr>();
local_free(box as *u8);
(*((*box).type_desc)).size
+ sys::size_of::<raw::Box<()>>();
local_free(box as *i8);
}
}
......
......@@ -14,27 +14,8 @@
#[cfg(not(test))] use cmp::{Eq, Ord};
pub mod raw {
use std::unstable::intrinsics::TyDesc;
pub static RC_MANAGED_UNIQUE : uint = (-2) as uint;
pub static RC_IMMORTAL : uint = 0x77777777;
#[allow(missing_doc)]
pub struct BoxHeaderRepr {
ref_count: uint,
type_desc: *TyDesc,
prev: *BoxRepr,
next: *BoxRepr,
}
#[allow(missing_doc)]
pub struct BoxRepr {
header: BoxHeaderRepr,
data: u8
}
}
pub static RC_MANAGED_UNIQUE : uint = (-2) as uint;
pub static RC_IMMORTAL : uint = 0x77777777;
/// Determine if two shared boxes point to the same object
#[inline]
......
......@@ -19,7 +19,7 @@
use unstable::intrinsics::{Opaque, TyDesc, TyVisitor};
use libc::c_void;
use sys;
use vec;
use unstable::raw;
/**
* Trait for visitor that wishes to reflect on data. To use this, create a
......@@ -260,7 +260,7 @@ fn visit_rptr(&self, mtbl: uint, inner: *TyDesc) -> bool {
}
fn visit_unboxed_vec(&self, mtbl: uint, inner: *TyDesc) -> bool {
self.align_to::<vec::UnboxedVecRepr>();
self.align_to::<raw::Vec<()>>();
if ! self.inner.visit_vec(mtbl, inner) { return false; }
true
}
......
......@@ -22,21 +22,17 @@
use io::{Writer, WriterUtil};
use iterator::IteratorUtil;
use libc::c_void;
use managed;
use ptr;
use reflect;
use reflect::{MovePtr, align};
use str::StrSlice;
use to_str::ToStr;
use vec::raw::{VecRepr, SliceRepr};
use vec;
use vec::{OwnedVector, UnboxedVecRepr};
use vec::OwnedVector;
use unstable::intrinsics::{Opaque, TyDesc, TyVisitor, get_tydesc, visit_tydesc};
use unstable::raw;
#[cfg(test)] use io;
pub use managed::raw::BoxRepr;
/// Helpers
trait EscapedCharWriter {
......@@ -198,11 +194,11 @@ pub fn write_mut_qualifier(&self, mtbl: uint) {
pub fn write_vec_range(&self,
_mtbl: uint,
ptr: *u8,
ptr: *(),
len: uint,
inner: *TyDesc)
-> bool {
let mut p = ptr;
let mut p = ptr as *u8;
let (sz, al) = unsafe { ((*inner).size, (*inner).align) };
self.writer.write_char('[');
let mut first = true;
......@@ -225,7 +221,7 @@ pub fn write_vec_range(&self,
pub fn write_unboxed_vec_repr(&self,
mtbl: uint,
v: &UnboxedVecRepr,
v: &raw::Vec<()>,
inner: *TyDesc)
-> bool {
self.write_vec_range(mtbl, ptr::to_unsafe_ptr(&v.data),
......@@ -289,7 +285,7 @@ fn visit_estr_fixed(&self, _n: uint, _sz: uint,
fn visit_box(&self, mtbl: uint, inner: *TyDesc) -> bool {
self.writer.write_char('@');
self.write_mut_qualifier(mtbl);
do self.get::<&managed::raw::BoxRepr> |b| {
do self.get::<&raw::Box<()>> |b| {
let p = ptr::to_unsafe_ptr(&b.data) as *c_void;
self.visit_ptr_inner(p, inner);
}
......@@ -304,7 +300,7 @@ fn visit_uniq(&self, _mtbl: uint, inner: *TyDesc) -> bool {
fn visit_uniq_managed(&self, _mtbl: uint, inner: *TyDesc) -> bool {
self.writer.write_char('~');
do self.get::<&managed::raw::BoxRepr> |b| {
do self.get::<&raw::Box<()>> |b| {
let p = ptr::to_unsafe_ptr(&b.data) as *c_void;
self.visit_ptr_inner(p, inner);
}
......@@ -330,35 +326,35 @@ fn visit_rptr(&self, mtbl: uint, inner: *TyDesc) -> bool {
fn visit_unboxed_vec(&self, mtbl: uint, inner: *TyDesc) -> bool {
do self.get::<vec::UnboxedVecRepr> |b| {
do self.get::<raw::Vec<()>> |b| {
self.write_unboxed_vec_repr(mtbl, b, inner);
}
}
fn visit_evec_box(&self, mtbl: uint, inner: *TyDesc) -> bool {
do self.get::<&VecRepr> |b| {
do self.get::<&raw::Box<raw::Vec<()>>> |b| {
self.writer.write_char('@');
self.write_mut_qualifier(mtbl);
self.write_unboxed_vec_repr(mtbl, &b.unboxed, inner);
self.write_unboxed_vec_repr(mtbl, &b.data, inner);
}
}
fn visit_evec_uniq(&self, mtbl: uint, inner: *TyDesc) -> bool {
do self.get::<&UnboxedVecRepr> |b| {
do self.get::<&raw::Vec<()>> |b| {
self.writer.write_char('~');
self.write_unboxed_vec_repr(mtbl, *b, inner);
}
}
fn visit_evec_uniq_managed(&self, mtbl: uint, inner: *TyDesc) -> bool {
do self.get::<&VecRepr> |b| {
do self.get::<&raw::Box<raw::Vec<()>>> |b| {
self.writer.write_char('~');
self.write_unboxed_vec_repr(mtbl, &b.unboxed, inner);
self.write_unboxed_vec_repr(mtbl, &b.data, inner);
}
}
fn visit_evec_slice(&self, mtbl: uint, inner: *TyDesc) -> bool {
do self.get::<SliceRepr> |s| {
do self.get::<raw::Slice<()>> |s| {
self.writer.write_char('&');
self.write_vec_range(mtbl, s.data, s.len, inner);
}
......@@ -366,7 +362,7 @@ fn visit_evec_slice(&self, mtbl: uint, inner: *TyDesc) -> bool {
fn visit_evec_fixed(&self, _n: uint, sz: uint, _align: uint,
mtbl: uint, inner: *TyDesc) -> bool {
do self.get::<u8> |b| {
do self.get::<()> |b| {
self.write_vec_range(mtbl, ptr::to_unsafe_ptr(b), sz, inner);
}
}
......@@ -547,9 +543,9 @@ fn visit_type(&self) -> bool { true }
fn visit_opaque_box(&self) -> bool {
self.writer.write_char('@');
do self.get::<&managed::raw::BoxRepr> |b| {
do self.get::<&raw::Box<()>> |b| {
let p = ptr::to_unsafe_ptr(&b.data) as *c_void;
self.visit_ptr_inner(p, b.header.type_desc);
self.visit_ptr_inner(p, b.type_desc);
}
}
......
......@@ -12,12 +12,12 @@
use libc::{c_char, c_void, size_t, STDERR_FILENO};
use io;
use io::{Writer, WriterUtil};
use managed::raw::BoxRepr;
use option::{Option, None, Some};
use uint;
use str;
use str::{OwnedStr, StrSlice};
use sys;
use unstable::raw;
use vec::ImmutableVector;
#[allow(non_camel_case_types)]
......@@ -29,7 +29,7 @@
#[deriving(Eq)]
struct BorrowRecord {
box: *mut BoxRepr,
box: *mut raw::Box<()>,
file: *c_char,
line: size_t
}
......@@ -70,7 +70,7 @@ pub unsafe fn clear_task_borrow_list() {
let _ = try_take_task_borrow_list();
}
unsafe fn fail_borrowed(box: *mut BoxRepr, file: *c_char, line: size_t) {
unsafe fn fail_borrowed(box: *mut raw::Box<()>, file: *c_char, line: size_t) {
debug_borrow("fail_borrowed: ", box, 0, 0, file, line);
match try_take_task_borrow_list() {
......@@ -172,8 +172,8 @@ unsafe fn write_cstr(&self, p: *c_char) {
#[inline]
pub unsafe fn borrow_as_imm(a: *u8, file: *c_char, line: size_t) -> uint {
let a: *mut BoxRepr = transmute(a);
let old_ref_count = (*a).header.ref_count;
let a = a as *mut raw::Box<()>;
let old_ref_count = (*a).ref_count;
let new_ref_count = old_ref_count | FROZEN_BIT;
debug_borrow("borrow_as_imm:", a, old_ref_count, new_ref_count, file, line);
......@@ -182,15 +182,15 @@ pub unsafe fn borrow_as_imm(a: *u8, file: *c_char, line: size_t) -> uint {
fail_borrowed(a, file, line);
}
(*a).header.ref_count = new_ref_count;
(*a).ref_count = new_ref_count;
old_ref_count
}
#[inline]
pub unsafe fn borrow_as_mut(a: *u8, file: *c_char, line: size_t) -> uint {
let a: *mut BoxRepr = transmute(a);
let old_ref_count = (*a).header.ref_count;
let a = a as *mut raw::Box<()>;
let old_ref_count = (*a).ref_count;
let new_ref_count = old_ref_count | MUT_BIT | FROZEN_BIT;
debug_borrow("borrow_as_mut:", a, old_ref_count, new_ref_count, file, line);
......@@ -199,7 +199,7 @@ pub unsafe fn borrow_as_mut(a: *u8, file: *c_char, line: size_t) -> uint {
fail_borrowed(a, file, line);
}
(*a).header.ref_count = new_ref_count;
(*a).ref_count = new_ref_count;
old_ref_count
}
......@@ -208,7 +208,7 @@ pub unsafe fn record_borrow(a: *u8, old_ref_count: uint,
file: *c_char, line: size_t) {
if (old_ref_count & ALL_BITS) == 0 {
// was not borrowed before
let a: *mut BoxRepr = transmute(a);
let a = a as *mut raw::Box<()>;
debug_borrow("record_borrow:", a, old_ref_count, 0, file, line);
do swap_task_borrow_list |borrow_list| {
let mut borrow_list = borrow_list;
......@@ -223,7 +223,7 @@ pub unsafe fn unrecord_borrow(a: *u8, old_ref_count: uint,
if (old_ref_count & ALL_BITS) == 0 {
// was not borrowed before, so we should find the record at
// the end of the list
let a: *mut BoxRepr = transmute(a);
let a = a as *mut raw::Box<()>;
debug_borrow("unrecord_borrow:", a, old_ref_count, 0, file, line);
do swap_task_borrow_list |borrow_list| {
let mut borrow_list = borrow_list;
......@@ -246,15 +246,15 @@ pub unsafe fn return_to_mut(a: *u8, orig_ref_count: uint,
// Sometimes the box is null, if it is conditionally frozen.
// See e.g. #4904.
if !a.is_null() {
let a: *mut BoxRepr = transmute(a);
let old_ref_count = (*a).header.ref_count;
let a = a as *mut raw::Box<()>;
let old_ref_count = (*a).ref_count;
let new_ref_count =
(old_ref_count & !ALL_BITS) | (orig_ref_count & ALL_BITS);
debug_borrow("return_to_mut:",
a, old_ref_count, new_ref_count, file, line);
(*a).header.ref_count = new_ref_count;
(*a).ref_count = new_ref_count;
}
}
......@@ -262,8 +262,8 @@ pub unsafe fn return_to_mut(a: *u8, orig_ref_count: uint,
pub unsafe fn check_not_borrowed(a: *u8,
file: *c_char,
line: size_t) {
let a: *mut BoxRepr = transmute(a);
let ref_count = (*a).header.ref_count;
let a = a as *mut raw::Box<()>;
let ref_count = (*a).ref_count;
debug_borrow("check_not_borrowed:", a, ref_count, 0, file, line);
if (ref_count & FROZEN_BIT) != 0 {
fail_borrowed(a, file, line);
......
......@@ -9,8 +9,8 @@
// except according to those terms.
use libc::{c_void, c_char, size_t, uintptr_t, free, malloc, realloc};
use managed::raw::{BoxHeaderRepr, BoxRepr};
use unstable::intrinsics::TyDesc;
use unstable::raw;
use sys::size_of;
extern {
......@@ -20,7 +20,7 @@
#[inline]
fn get_box_size(body_size: uint, body_align: uint) -> uint {
let header_size = size_of::<BoxHeaderRepr>();
let header_size = size_of::<raw::Box<()>>();
// FIXME (#2699): This alignment calculation is suspicious. Is it right?
let total_size = align_to(header_size, body_align) + body_size;
total_size
......@@ -82,8 +82,8 @@ pub unsafe fn closure_exchange_malloc(td: *c_char, size: uintptr_t) -> *c_char {
let total_size = get_box_size(size, (*td).align);
let p = malloc_raw(total_size as uint);
let box: *mut BoxRepr = p as *mut BoxRepr;
(*box).header.type_desc = td;
let box = p as *mut raw::Box<()>;
(*box).type_desc = td;
box as *c_char
}
......
......@@ -13,11 +13,11 @@
use libc;
use libc::{c_void, uintptr_t, size_t};
use ops::Drop;
use repr::BoxRepr;
use rt;
use rt::OldTaskContext;
use rt::local::Local;
use rt::task::Task;
use unstable::raw;
type MemoryRegion = c_void;
......@@ -26,7 +26,7 @@ struct Env { priv opaque: () }
struct BoxedRegion {
env: *Env,
backing_region: *MemoryRegion,
live_allocs: *BoxRepr
live_allocs: *raw::Box<()>,
}
pub type OpaqueBox = c_void;
......@@ -103,7 +103,7 @@ pub unsafe fn local_free(ptr: *libc::c_char) {
}
}
pub fn live_allocs() -> *BoxRepr {
pub fn live_allocs() -> *raw::Box<()> {
let region = match rt::context() {
OldTaskContext => {
unsafe { rust_current_boxed_region() }
......
......@@ -10,9 +10,9 @@
use either::{Left, Right};
use option::{Option, Some, None};
use sys;
use cast::transmute;
use clone::Clone;
use unstable::raw;
use super::sleeper_list::SleeperList;
use super::work_queue::WorkQueue;
......@@ -698,7 +698,7 @@ pub fn send(&mut self, msg: SchedMessage) {
// XXX: Some hacks to put a &fn in Scheduler without borrowck
// complaining
type UnsafeTaskReceiver = sys::Closure;
type UnsafeTaskReceiver = raw::Closure;
trait ClosureConverter {
fn from_fn(&fn(&mut Scheduler, BlockedTask)) -> Self;
fn to_fn(self) -> &fn(&mut Scheduler, BlockedTask);
......
......@@ -281,7 +281,7 @@ pub fn recycle(~self, stack_pool: &mut StackPool) {
impl Unwinder {
pub fn try(&mut self, f: &fn()) {
use sys::Closure;
use unstable::raw::Closure;
unsafe {
let closure: Closure = transmute(f);
......
......@@ -31,6 +31,7 @@
use ptr::RawPtr;
use to_str::ToStr;
use uint;
use unstable::raw::Repr;
use vec;
use vec::{OwnedVector, OwnedCopyableVector, ImmutableVector, MutableVector};
......@@ -114,9 +115,9 @@ pub fn from_bytes_with_null<'a>(vv: &'a [u8]) -> &'a str {
pub fn from_bytes_slice<'a>(vector: &'a [u8]) -> &'a str {
unsafe {
assert!(is_utf8(vector));
let (ptr, len): (*u8, uint) = ::cast::transmute(vector);
let string: &'a str = ::cast::transmute((ptr, len + 1));
string
let mut s = vector.repr();
s.len += 1;
cast::transmute(s)
}
}
......@@ -142,7 +143,7 @@ fn to_str(&self) -> ~str { self.to_owned() }
*/
pub fn from_byte(b: u8) -> ~str {
assert!(b < 128u8);
unsafe { ::cast::transmute(~[b, 0u8]) }
unsafe { cast::transmute(~[b, 0u8]) }
}
/// Convert a char to a string
......@@ -217,7 +218,7 @@ pub fn connect(&self, sep: &str) -> ~str {
do s.as_mut_buf |buf, _| {
do sep.as_imm_buf |sepbuf, seplen| {
let seplen = seplen - 1;
let mut buf = ::cast::transmute_mut_unsafe(buf);
let mut buf = cast::transmute_mut_unsafe(buf);
for self.iter().advance |ss| {
do ss.as_slice().as_imm_buf |ssbuf, sslen| {
let sslen = sslen - 1;
......@@ -771,10 +772,10 @@ pub mod raw {
use cast;
use libc;
use ptr;
use str::raw;
use str::{is_utf8};
use str::is_utf8;
use vec;
use vec::MutableVector;
use unstable::raw::{Slice, String};
/// Create a Rust string from a null-terminated *u8 buffer
pub unsafe fn from_buf(buf: *u8) -> ~str {
......@@ -797,17 +798,17 @@ pub unsafe fn from_buf_len(buf: *u8, len: uint) -> ~str {
v.push(0u8);
assert!(is_utf8(v));
return ::cast::transmute(v);
return cast::transmute(v);
}
/// Create a Rust string from a null-terminated C string
pub unsafe fn from_c_str(c_str: *libc::c_char) -> ~str {
from_buf(::cast::transmute(c_str))
from_buf(c_str as *u8)
}
/// Create a Rust string from a `*c_char` buffer of the given length
pub unsafe fn from_c_str_len(c_str: *libc::c_char, len: uint) -> ~str {
from_buf_len(::cast::transmute(c_str), len)
from_buf_len(c_str as *u8, len)
}
/// Converts a vector of bytes to a new owned string.
......@@ -832,7 +833,7 @@ pub unsafe fn from_bytes_with_null<'a>(v: &'a [u8]) -> &'a str {
}
/// Converts a byte to a string.
pub unsafe fn from_byte(u: u8) -> ~str { raw::from_bytes([u]) }
pub unsafe fn from_byte(u: u8) -> ~str { from_bytes([u]) }
/// Form a slice from a C string. Unsafe because the caller must ensure the
/// C string has the static lifetime, or else the return value may be
......@@ -845,9 +846,9 @@ pub unsafe fn c_str_to_static_slice(s: *libc::c_char) -> &'static str {
len += 1u;
curr = ptr::offset(s, len);
}
let v = (s, len + 1);
assert!(is_utf8(::cast::transmute(v)));
::cast::transmute(v)
let v = Slice { data: s, len: len + 1 };
assert!(is_utf8(cast::transmute(v)));
cast::transmute(v)
}
/**
......@@ -866,8 +867,10 @@ pub unsafe fn slice_bytes(s: &str, begin: uint, end: uint) -> &str {
assert!((begin <= end));
assert!((end <= n));
let tuple = (ptr::offset(sbuf, begin), end - begin + 1);
::cast::transmute(tuple)
cast::transmute(Slice {
data: ptr::offset(sbuf, begin),
len: end - begin + 1,
})
}
}
......@@ -909,11 +912,10 @@ pub unsafe fn shift_byte(s: &mut ~str) -> u8 {
/// Sets the length of the string and adds the null terminator
#[inline]
pub unsafe fn set_len(v: &mut ~str, new_len: uint) {
let v: **mut vec::UnboxedVecRepr = cast::transmute(v);
let repr: *mut vec::UnboxedVecRepr = *v;
let v: **mut String = cast::transmute(v);
let repr = *v;
(*repr).fill = new_len + 1u;
let null = ptr::mut_offset(cast::transmute(&((*repr).data)),
new_len);
let null = ptr::mut_offset(&mut ((*repr).data), new_len);
*null = 0u8;
}
......@@ -1595,7 +1597,7 @@ fn to_managed(&self) -> @str {
let v = at_vec::from_fn(self.len() + 1, |i| {
if i == self.len() { 0 } else { self[i] }
});
unsafe { ::cast::transmute(v) }
unsafe { cast::transmute(v) }
}
/// Converts to a vector of `u16` encoded as UTF-16.
......@@ -1750,9 +1752,9 @@ fn char_at_reverse(&self, i: uint) -> char {
*/
fn as_bytes(&self) -> &'self [u8] {
unsafe {
let (ptr, len): (*u8, uint) = ::cast::transmute(*self);
let outgoing_tuple: (*u8, uint) = (ptr, len - 1);
::cast::transmute(outgoing_tuple)
let mut slice = self.repr();
slice.len -= 1;
cast::transmute(slice)
}
}
......@@ -2001,7 +2003,7 @@ impl NullTerminatedStr for ~str {
*/
#[inline]
fn as_bytes_with_null<'a>(&'a self) -> &'a [u8] {
let ptr: &'a ~[u8] = unsafe { ::cast::transmute(self) };
let ptr: &'a ~[u8] = unsafe { cast::transmute(self) };
let slice: &'a [u8] = *ptr;
slice
}
......@@ -2014,7 +2016,7 @@ impl NullTerminatedStr for @str {
*/
#[inline]
fn as_bytes_with_null<'a>(&'a self) -> &'a [u8] {
let ptr: &'a @[u8] = unsafe { ::cast::transmute(self) };
let ptr: &'a @[u8] = unsafe { cast::transmute(self) };
let slice: &'a [u8] = *ptr;
slice
}
......@@ -2058,7 +2060,7 @@ fn push_str_no_overallocate(&mut self, rhs: &str) {
do self.as_imm_buf |lbuf, _llen| {
do rhs.as_imm_buf |rbuf, _rlen| {
let dst = ptr::offset(lbuf, llen);
let dst = ::cast::transmute_mut_unsafe(dst);
let dst = cast::transmute_mut_unsafe(dst);
ptr::copy_memory(dst, rbuf, rlen);
}
}
......@@ -2076,7 +2078,7 @@ fn push_str(&mut self, rhs: &str) {
do self.as_imm_buf |lbuf, _llen| {
do rhs.as_imm_buf |rbuf, _rlen| {
let dst = ptr::offset(lbuf, llen);
let dst = ::cast::transmute_mut_unsafe(dst);
let dst = cast::transmute_mut_unsafe(dst);
ptr::copy_memory(dst, rbuf, rlen);
}
}
......@@ -2232,7 +2234,7 @@ fn capacity(&self) -> uint {
/// string, and includes the null terminator.
#[inline]
fn to_bytes_with_null(self) -> ~[u8] {
unsafe { ::cast::transmute(self) }
unsafe { cast::transmute(self) }
}
#[inline]
......
......@@ -22,12 +22,6 @@
use str;
use unstable::intrinsics;
/// The representation of a Rust closure
pub struct Closure {
code: *(),
env: *(),
}
pub mod rustrt {
use libc::{c_char, size_t};
......@@ -278,6 +272,7 @@ fn align_of_val_basic() {
#[test]
fn synthesize_closure() {
use unstable::raw::Closure;
unsafe {
let x = 10;
let f: &fn(int) -> int = |y| x + y;
......
......@@ -15,8 +15,8 @@
use local_data;
use prelude::*;
use ptr;
use sys;
use task::rt;
use unstable::raw;
use util;
use super::rt::rust_task;
......@@ -158,7 +158,7 @@ unsafe fn newsched_map(local: *mut LocalStorage) -> &mut TaskLocalMap {
}
unsafe fn key_to_key_value<T: 'static>(key: local_data::Key<T>) -> *libc::c_void {
let pair: sys::Closure = cast::transmute_copy(&key);
let pair: raw::Closure = cast::transmute_copy(&key);
return pair.code as *libc::c_void;
}
......
......@@ -26,6 +26,7 @@
pub mod lang;
pub mod sync;
pub mod atomics;
pub mod raw;
/**
......
// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use cast;
use unstable::intrinsics::TyDesc;
/// The representation of a Rust managed box
pub struct Box<T> {
ref_count: uint,
type_desc: *TyDesc,
prev: *Box<T>,
next: *Box<T>,
data: T
}
/// The representation of a Rust vector
pub struct Vec<T> {
fill: uint,
alloc: uint,
data: T
}
/// The representation of a Rust string
pub type String = Vec<u8>;
/// The representation of a Rust slice
pub struct Slice<T> {
data: *T,
len: uint
}
/// The representation of a Rust closure
pub struct Closure {
code: *(),
env: *(),
}
/// This trait is meant to map equivalences between raw structs and their
/// corresponding rust values.
pub trait Repr<T> {
/// This function "unwraps" a rust value (without consuming it) into its raw
/// struct representation. This can be used to read/write different values
/// for the struct. This is a safe method because by default it does not
/// give write-access to the struct returned.
fn repr(&self) -> T { unsafe { cast::transmute_copy(self) } }
}
impl<'self, T> Repr<Slice<T>> for &'self [T] {}
impl<'self> Repr<Slice<u8>> for &'self str {}
impl<T> Repr<*Box<T>> for @T {}
impl<T> Repr<*Box<Vec<T>>> for @[T] {}
// sure would be nice to have this
// impl<T> Repr<*Vec<T>> for ~[T] {}
......@@ -12,7 +12,6 @@
#[warn(non_camel_case_types)];
use cast::transmute;
use cast;
use clone::Clone;
use container::{Container, Mutable};
......@@ -32,6 +31,7 @@
use uint;
use unstable::intrinsics;
use unstable::intrinsics::{get_tydesc, contains_managed};
use unstable::raw::{Box, Repr, Slice, Vec};
use vec;
use util;
......@@ -96,7 +96,7 @@ pub fn with_capacity<T>(capacity: uint) -> ~[T] {
vec
} else {
let alloc = capacity * sys::nonzero_size_of::<T>();
let ptr = malloc_raw(alloc + sys::size_of::<UnboxedVecRepr>()) as *mut UnboxedVecRepr;
let ptr = malloc_raw(alloc + sys::size_of::<Vec<()>>()) as *mut Vec<()>;
(*ptr).alloc = alloc;
(*ptr).fill = 0;
cast::transmute(ptr)
......@@ -736,8 +736,10 @@ fn slice(&self, start: uint, end: uint) -> &'self [T] {
assert!(end <= self.len());
do self.as_imm_buf |p, _len| {
unsafe {
transmute((ptr::offset(p, start),
(end - start) * sys::nonzero_size_of::<T>()))
cast::transmute(Slice {
data: ptr::offset(p, start),
len: (end - start) * sys::nonzero_size_of::<T>(),
})
}
}
}
......@@ -767,8 +769,8 @@ fn iter(self) -> VecIterator<'self, T> {
unsafe {
let p = vec::raw::to_ptr(self);
VecIterator{ptr: p,
end: cast::transmute(p as uint + self.len() *
sys::nonzero_size_of::<T>()),
end: (p as uint + self.len() *
sys::nonzero_size_of::<T>()) as *T,
lifetime: cast::transmute(p)}
}
}
......@@ -947,8 +949,7 @@ fn flat_map<U>(&self, f: &fn(t: &T) -> ~[U]) -> ~[U] {
/// bounds checking.
#[inline]
unsafe fn unsafe_ref(&self, index: uint) -> *T {
let (ptr, _): (*T, uint) = transmute(*self);
ptr.offset(index)
self.repr().data.offset(index)
}
/**
......@@ -1002,11 +1003,8 @@ fn as_imm_buf<U>(&self,
// into `s` and pass them to `f()`, but in fact they are potentially
// pointing at *mutable memory*. Use `as_mut_buf` instead!
unsafe {
let v : *(*T,uint) = transmute(self);
let (buf,len) = *v;
f(buf, len / sys::nonzero_size_of::<T>())
}
let s = self.repr();
f(s.data, s.len / sys::nonzero_size_of::<T>())
}
}
......@@ -1158,17 +1156,17 @@ fn reserve(&mut self, n: uint) {
unsafe {
let td = get_tydesc::<T>();
if contains_managed::<T>() {
let ptr: *mut *mut raw::VecRepr = cast::transmute(self);
let ptr: *mut *mut Box<Vec<()>> = cast::transmute(self);
::at_vec::raw::reserve_raw(td, ptr, n);
} else {
let ptr: *mut *mut UnboxedVecRepr = cast::transmute(self);
let ptr: *mut *mut Vec<()> = cast::transmute(self);
let alloc = n * sys::nonzero_size_of::<T>();
let size = alloc + sys::size_of::<UnboxedVecRepr>();
let size = alloc + sys::size_of::<Vec<()>>();
if alloc / sys::nonzero_size_of::<T>() != n || size < alloc {
fail!("vector size is too large: %u", n);
}
*ptr = realloc_raw(*ptr as *mut c_void, size)
as *mut UnboxedVecRepr;
as *mut Vec<()>;
(**ptr).alloc = alloc;
}
}
......@@ -1198,10 +1196,10 @@ fn reserve_at_least(&mut self, n: uint) {
fn capacity(&self) -> uint {
unsafe {
if contains_managed::<T>() {
let repr: **raw::VecRepr = transmute(self);
(**repr).unboxed.alloc / sys::nonzero_size_of::<T>()
let repr: **Box<Vec<()>> = cast::transmute(self);
(**repr).data.alloc / sys::nonzero_size_of::<T>()
} else {
let repr: **UnboxedVecRepr = transmute(self);
let repr: **Vec<()> = cast::transmute(self);
(**repr).alloc / sys::nonzero_size_of::<T>()
}
}
......@@ -1212,16 +1210,16 @@ fn capacity(&self) -> uint {
fn push(&mut self, t: T) {
unsafe {
if contains_managed::<T>() {
let repr: **raw::VecRepr = transmute(&mut *self);
let fill = (**repr).unboxed.fill;
if (**repr).unboxed.alloc <= fill {
let repr: **Box<Vec<()>> = cast::transmute(&mut *self);
let fill = (**repr).data.fill;
if (**repr).data.alloc <= fill {
let new_len = self.len() + 1;
self.reserve_at_least(new_len);
}
self.push_fast(t);
} else {
let repr: **UnboxedVecRepr = transmute(&mut *self);
let repr: **Vec<()> = cast::transmute(&mut *self);
let fill = (**repr).fill;
if (**repr).alloc <= fill {
let new_len = self.len() + 1;
......@@ -1237,14 +1235,14 @@ fn push(&mut self, t: T) {
#[inline] // really pretty please
unsafe fn push_fast(&mut self, t: T) {
if contains_managed::<T>() {
let repr: **mut raw::VecRepr = transmute(self);
let fill = (**repr).unboxed.fill;
(**repr).unboxed.fill += sys::nonzero_size_of::<T>();
let p = to_unsafe_ptr(&((**repr).unboxed.data));
let repr: **mut Box<Vec<u8>> = cast::transmute(self);
let fill = (**repr).data.fill;
(**repr).data.fill += sys::nonzero_size_of::<T>();
let p = to_unsafe_ptr(&((**repr).data.data));
let p = ptr::offset(p, fill) as *mut T;
intrinsics::move_val_init(&mut(*p), t);
} else {
let repr: **mut UnboxedVecRepr = transmute(self);
let repr: **mut Vec<u8> = cast::transmute(self);
let fill = (**repr).fill;
(**repr).fill += sys::nonzero_size_of::<T>();
let p = to_unsafe_ptr(&((**repr).data));
......@@ -1338,14 +1336,14 @@ fn shift_opt(&mut self) -> Option<T> {
{
let first_slice = self.slice(0, 1);
let last_slice = self.slice(next_ln, ln);
raw::copy_memory(transmute(last_slice), first_slice, 1);
raw::copy_memory(cast::transmute(last_slice), first_slice, 1);
}
// Memcopy everything to the left one element
{
let init_slice = self.slice(0, next_ln);
let tail_slice = self.slice(1, ln);
raw::copy_memory(transmute(init_slice),
raw::copy_memory(cast::transmute(init_slice),
tail_slice,
next_ln);
}
......@@ -1689,8 +1687,8 @@ fn mut_split(self, mid: uint) -> (&'self mut [T],
*/
fn move_from(self, src: ~[T], start: uint, end: uint) -> uint;
unsafe fn unsafe_mut_ref(&self, index: uint) -> *mut T;
unsafe fn unsafe_set(&self, index: uint, val: T);
unsafe fn unsafe_mut_ref(self, index: uint) -> *mut T;
unsafe fn unsafe_set(self, index: uint, val: T);
fn as_mut_buf<U>(self, f: &fn(*mut T, uint) -> U) -> U;
}
......@@ -1703,8 +1701,10 @@ fn mut_slice(self, start: uint, end: uint) -> &'self mut [T] {
assert!(end <= self.len());
do self.as_mut_buf |p, _len| {
unsafe {
transmute((ptr::mut_offset(p, start),
(end - start) * sys::nonzero_size_of::<T>()))
cast::transmute(Slice {
data: ptr::mut_offset(p, start) as *T,
len: (end - start) * sys::nonzero_size_of::<T>()
})
}
}
}
......@@ -1723,8 +1723,8 @@ fn mut_iter(self) -> VecMutIterator<'self, T> {
unsafe {
let p = vec::raw::to_mut_ptr(self);
VecMutIterator{ptr: p,
end: cast::transmute(p as uint + self.len() *
sys::nonzero_size_of::<T>()),
end: (p as uint + self.len() *
sys::nonzero_size_of::<T>()) as *mut T,
lifetime: cast::transmute(p)}
}
}
......@@ -1771,22 +1771,20 @@ fn move_from(self, mut src: ~[T], start: uint, end: uint) -> uint {
}
#[inline]
unsafe fn unsafe_mut_ref(&self, index: uint) -> *mut T {
let pair_ptr: &(*mut T, uint) = transmute(self);
let (ptr, _) = *pair_ptr;
ptr.offset(index)
unsafe fn unsafe_mut_ref(self, index: uint) -> *mut T {
ptr::mut_offset(self.repr().data as *mut T, index)
}
#[inline]
unsafe fn unsafe_set(&self, index: uint, val: T) {
unsafe fn unsafe_set(self, index: uint, val: T) {
*self.unsafe_mut_ref(index) = val;
}
/// Similar to `as_imm_buf` but passing a `*mut T`
#[inline]
fn as_mut_buf<U>(self, f: &fn(*mut T, uint) -> U) -> U {
let (buf, len): (*mut T, uint) = unsafe { transmute(self) };
f(buf, len / sys::nonzero_size_of::<T>())
let Slice{ data, len } = self.repr();
f(data as *mut T, len / sys::nonzero_size_of::<T>())
}
}
......@@ -1821,40 +1819,17 @@ pub unsafe fn from_buf<T>(ptr: *T, elts: uint) -> ~[T] {
raw::from_buf_raw(ptr, elts)
}
/// The internal 'unboxed' representation of a vector
#[allow(missing_doc)]
pub struct UnboxedVecRepr {
fill: uint,
alloc: uint,
data: u8
}
/// Unsafe operations
pub mod raw {
use cast::transmute;
use cast;
use clone::Clone;
use managed;
use option::Some;
use ptr;
use sys;
use unstable::intrinsics;
use vec::{UnboxedVecRepr, with_capacity, ImmutableVector, MutableVector};
use vec::{with_capacity, ImmutableVector, MutableVector};
use unstable::intrinsics::contains_managed;
/// The internal representation of a (boxed) vector
#[allow(missing_doc)]
pub struct VecRepr {
box_header: managed::raw::BoxHeaderRepr,
unboxed: UnboxedVecRepr
}
/// The internal representation of a slice
pub struct SliceRepr {
/// Pointer to the base of this slice
data: *u8,
/// The length of the slice
len: uint
}
use unstable::raw::{Box, Vec, Slice};
/**
* Sets the length of a vector
......@@ -1866,10 +1841,10 @@ pub struct SliceRepr {
#[inline]
pub unsafe fn set_len<T>(v: &mut ~[T], new_len: uint) {
if contains_managed::<T>() {
let repr: **mut VecRepr = transmute(v);
(**repr).unboxed.fill = new_len * sys::nonzero_size_of::<T>();
let repr: **mut Box<Vec<()>> = cast::transmute(v);
(**repr).data.fill = new_len * sys::nonzero_size_of::<T>();
} else {
let repr: **mut UnboxedVecRepr = transmute(v);
let repr: **mut Vec<()> = cast::transmute(v);
(**repr).fill = new_len * sys::nonzero_size_of::<T>();
}
}
......@@ -1885,19 +1860,13 @@ pub unsafe fn set_len<T>(v: &mut ~[T], new_len: uint) {
*/
#[inline]
pub fn to_ptr<T>(v: &[T]) -> *T {
unsafe {
let repr: **SliceRepr = transmute(&v);
transmute(&((**repr).data))
}
v.repr().data
}
/** see `to_ptr()` */
#[inline]
pub fn to_mut_ptr<T>(v: &mut [T]) -> *mut T {
unsafe {
let repr: **SliceRepr = transmute(&v);
transmute(&((**repr).data))
}
v.repr().data as *mut T
}
/**
......@@ -1908,9 +1877,10 @@ pub fn to_mut_ptr<T>(v: &mut [T]) -> *mut T {
pub unsafe fn buf_as_slice<T,U>(p: *T,
len: uint,
f: &fn(v: &[T]) -> U) -> U {
let pair = (p, len * sys::nonzero_size_of::<T>());
let v : *(&'blk [T]) = transmute(&pair);
f(*v)
f(cast::transmute(Slice {
data: p,
len: len * sys::nonzero_size_of::<T>()
}))
}
/**
......@@ -1921,9 +1891,10 @@ pub unsafe fn buf_as_slice<T,U>(p: *T,
pub unsafe fn mut_buf_as_slice<T,U>(p: *mut T,
len: uint,
f: &fn(v: &mut [T]) -> U) -> U {
let pair = (p, len * sys::nonzero_size_of::<T>());
let v : *(&'blk mut [T]) = transmute(&pair);
f(*v)
f(cast::transmute(Slice {
data: p as *T,
len: len * sys::nonzero_size_of::<T>()
}))
}
/**
......
......@@ -14,8 +14,8 @@
use std::libc::c_void;
use std::ptr;
use std::sys;
use std::vec::UnboxedVecRepr;
use std::unstable::intrinsics::{TyDesc, get_tydesc, visit_tydesc, TyVisitor, Opaque};
use std::unstable::raw::Vec;
#[doc = "High-level interfaces to `std::unstable::intrinsics::visit_ty` reflection system."]
......@@ -247,7 +247,7 @@ fn visit_rptr(&self, mtbl: uint, inner: *TyDesc) -> bool {
}
fn visit_unboxed_vec(&self, mtbl: uint, inner: *TyDesc) -> bool {
self.align_to::<UnboxedVecRepr>();
self.align_to::<Vec<()>>();
// FIXME (#3732): Inner really has to move its own pointers on this one.
// or else possibly we could have some weird interface wherein we
// read-off a word from inner's pointers, but the read-word has to
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册