new snapshot
This commit is contained in:
parent
fc05819181
commit
ed67cdb73c
33 changed files with 22 additions and 811 deletions
|
@ -305,7 +305,6 @@ struct RWARCInner<T> { priv lock: RWlock, priv failed: bool, priv data: T }
|
||||||
*
|
*
|
||||||
* Unlike mutex_arcs, rw_arcs are safe, because they cannot be nested.
|
* Unlike mutex_arcs, rw_arcs are safe, because they cannot be nested.
|
||||||
*/
|
*/
|
||||||
#[mutable] // XXX remove after snap
|
|
||||||
#[no_freeze]
|
#[no_freeze]
|
||||||
struct RWARC<T> {
|
struct RWARC<T> {
|
||||||
priv x: UnsafeAtomicRcBox<RWARCInner<T>>,
|
priv x: UnsafeAtomicRcBox<RWARCInner<T>>,
|
||||||
|
|
|
@ -46,15 +46,7 @@ use std::sys;
|
||||||
use std::uint;
|
use std::uint;
|
||||||
use std::vec;
|
use std::vec;
|
||||||
use std::unstable::intrinsics;
|
use std::unstable::intrinsics;
|
||||||
use std::unstable::intrinsics::{TyDesc};
|
use std::unstable::intrinsics::{TyDesc, get_tydesc};
|
||||||
|
|
||||||
#[cfg(not(stage0))]
|
|
||||||
use std::unstable::intrinsics::{get_tydesc};
|
|
||||||
|
|
||||||
#[cfg(stage0)]
|
|
||||||
unsafe fn get_tydesc<T>() -> *TyDesc {
|
|
||||||
intrinsics::get_tydesc::<T>() as *TyDesc
|
|
||||||
}
|
|
||||||
|
|
||||||
// The way arena uses arrays is really deeply awful. The arrays are
|
// The way arena uses arrays is really deeply awful. The arrays are
|
||||||
// allocated, and have capacities reserved, but the fill for the array
|
// allocated, and have capacities reserved, but the fill for the array
|
||||||
|
@ -65,7 +57,6 @@ struct Chunk {
|
||||||
is_pod: bool,
|
is_pod: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[mutable] // XXX remove after snap
|
|
||||||
#[no_freeze]
|
#[no_freeze]
|
||||||
pub struct Arena {
|
pub struct Arena {
|
||||||
// The head is separated out from the list as a unbenchmarked
|
// The head is separated out from the list as a unbenchmarked
|
||||||
|
@ -117,19 +108,6 @@ fn round_up_to(base: uint, align: uint) -> uint {
|
||||||
(base + (align - 1)) & !(align - 1)
|
(base + (align - 1)) & !(align - 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
#[cfg(not(stage0))]
|
|
||||||
unsafe fn call_drop_glue(tydesc: *TyDesc, data: *i8) {
|
|
||||||
// This function should be inlined when stage0 is gone
|
|
||||||
((*tydesc).drop_glue)(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
#[cfg(stage0)]
|
|
||||||
unsafe fn call_drop_glue(tydesc: *TyDesc, data: *i8) {
|
|
||||||
((*tydesc).drop_glue)(0 as **TyDesc, data);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Walk down a chunk, running the destructors for any objects stored
|
// Walk down a chunk, running the destructors for any objects stored
|
||||||
// in it.
|
// in it.
|
||||||
unsafe fn destroy_chunk(chunk: &Chunk) {
|
unsafe fn destroy_chunk(chunk: &Chunk) {
|
||||||
|
@ -149,7 +127,7 @@ unsafe fn destroy_chunk(chunk: &Chunk) {
|
||||||
//debug!("freeing object: idx = %u, size = %u, align = %u, done = %b",
|
//debug!("freeing object: idx = %u, size = %u, align = %u, done = %b",
|
||||||
// start, size, align, is_done);
|
// start, size, align, is_done);
|
||||||
if is_done {
|
if is_done {
|
||||||
call_drop_glue(tydesc, ptr::offset(buf, start) as *i8);
|
((*tydesc).drop_glue)(ptr::offset(buf, start) as *i8);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Find where the next tydesc lives
|
// Find where the next tydesc lives
|
||||||
|
|
|
@ -13,15 +13,9 @@
|
||||||
#[allow(missing_doc)];
|
#[allow(missing_doc)];
|
||||||
|
|
||||||
use std::cast::transmute;
|
use std::cast::transmute;
|
||||||
#[cfg(stage0)]
|
|
||||||
use intrinsic::{get_tydesc};
|
|
||||||
#[cfg(not(stage0))]
|
|
||||||
use std::unstable::intrinsics::{get_tydesc};
|
use std::unstable::intrinsics::{get_tydesc};
|
||||||
|
|
||||||
pub mod rustrt {
|
pub mod rustrt {
|
||||||
#[cfg(stage0)]
|
|
||||||
use intrinsic::{TyDesc};
|
|
||||||
#[cfg(not(stage0))]
|
|
||||||
use std::unstable::intrinsics::{TyDesc};
|
use std::unstable::intrinsics::{TyDesc};
|
||||||
|
|
||||||
#[abi = "cdecl"]
|
#[abi = "cdecl"]
|
||||||
|
|
|
@ -166,9 +166,7 @@ struct RcMutBox<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Mutable reference counted pointer type
|
/// Mutable reference counted pointer type
|
||||||
#[non_owned]
|
|
||||||
#[no_send]
|
#[no_send]
|
||||||
#[mutable] // XXX remove after snap
|
|
||||||
#[no_freeze]
|
#[no_freeze]
|
||||||
#[unsafe_no_drop_flag]
|
#[unsafe_no_drop_flag]
|
||||||
pub struct RcMut<T> {
|
pub struct RcMut<T> {
|
||||||
|
|
|
@ -68,10 +68,7 @@ pub unsafe fn read(prompt: &str) -> Option<~str> {
|
||||||
|
|
||||||
pub type CompletionCb = @fn(~str, @fn(~str));
|
pub type CompletionCb = @fn(~str, @fn(~str));
|
||||||
|
|
||||||
#[cfg(not(stage0))]
|
|
||||||
static complete_key: local_data::Key<@CompletionCb> = &local_data::Key;
|
static complete_key: local_data::Key<@CompletionCb> = &local_data::Key;
|
||||||
#[cfg(stage0)]
|
|
||||||
fn complete_key(_: @CompletionCb) {}
|
|
||||||
|
|
||||||
/// Bind to the main completion callback
|
/// Bind to the main completion callback
|
||||||
pub unsafe fn complete(cb: CompletionCb) {
|
pub unsafe fn complete(cb: CompletionCb) {
|
||||||
|
|
|
@ -106,7 +106,6 @@ pub mod jit {
|
||||||
use metadata::cstore;
|
use metadata::cstore;
|
||||||
|
|
||||||
use std::cast;
|
use std::cast;
|
||||||
#[cfg(not(stage0))]
|
|
||||||
use std::local_data;
|
use std::local_data;
|
||||||
use std::unstable::intrinsics;
|
use std::unstable::intrinsics;
|
||||||
|
|
||||||
|
@ -204,22 +203,15 @@ pub mod jit {
|
||||||
|
|
||||||
// The stage1 compiler won't work, but that doesn't really matter. TLS
|
// The stage1 compiler won't work, but that doesn't really matter. TLS
|
||||||
// changed only very recently to allow storage of owned values.
|
// changed only very recently to allow storage of owned values.
|
||||||
#[cfg(not(stage0))]
|
|
||||||
static engine_key: local_data::Key<~Engine> = &local_data::Key;
|
static engine_key: local_data::Key<~Engine> = &local_data::Key;
|
||||||
|
|
||||||
#[cfg(not(stage0))]
|
|
||||||
fn set_engine(engine: ~Engine) {
|
fn set_engine(engine: ~Engine) {
|
||||||
local_data::set(engine_key, engine)
|
local_data::set(engine_key, engine)
|
||||||
}
|
}
|
||||||
#[cfg(stage0)]
|
|
||||||
fn set_engine(_: ~Engine) {}
|
|
||||||
|
|
||||||
#[cfg(not(stage0))]
|
|
||||||
pub fn consume_engine() -> Option<~Engine> {
|
pub fn consume_engine() -> Option<~Engine> {
|
||||||
local_data::pop(engine_key)
|
local_data::pop(engine_key)
|
||||||
}
|
}
|
||||||
#[cfg(stage0)]
|
|
||||||
pub fn consume_engine() -> Option<~Engine> { None }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub mod write {
|
pub mod write {
|
||||||
|
|
|
@ -90,10 +90,7 @@ use syntax::abi::{X86, X86_64, Arm, Mips};
|
||||||
|
|
||||||
pub use middle::trans::context::task_llcx;
|
pub use middle::trans::context::task_llcx;
|
||||||
|
|
||||||
#[cfg(not(stage0))]
|
|
||||||
static task_local_insn_key: local_data::Key<@~[&'static str]> = &local_data::Key;
|
static task_local_insn_key: local_data::Key<@~[&'static str]> = &local_data::Key;
|
||||||
#[cfg(stage0)]
|
|
||||||
fn task_local_insn_key(_: @~[&'static str]) {}
|
|
||||||
|
|
||||||
pub fn with_insn_ctxt(blk: &fn(&[&'static str])) {
|
pub fn with_insn_ctxt(blk: &fn(&[&'static str])) {
|
||||||
let opt = local_data::get(task_local_insn_key, |k| k.map(|&k| *k));
|
let opt = local_data::get(task_local_insn_key, |k| k.map(|&k| *k));
|
||||||
|
|
|
@ -236,9 +236,6 @@ impl Drop for CrateContext {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(stage0)]
|
|
||||||
fn task_local_llcx_key(_v: @ContextRef) {}
|
|
||||||
#[cfg(not(stage0))]
|
|
||||||
static task_local_llcx_key: local_data::Key<@ContextRef> = &local_data::Key;
|
static task_local_llcx_key: local_data::Key<@ContextRef> = &local_data::Key;
|
||||||
|
|
||||||
pub fn task_llcx() -> ContextRef {
|
pub fn task_llcx() -> ContextRef {
|
||||||
|
|
|
@ -607,9 +607,6 @@ fn tuple_metadata(cx: &mut CrateContext,
|
||||||
span);
|
span);
|
||||||
}
|
}
|
||||||
|
|
||||||
// The stage0 snapshot does not yet support the fixes from PR #7557, so there are two versions of
|
|
||||||
// following function for now
|
|
||||||
#[cfg(not(stage0))]
|
|
||||||
fn enum_metadata(cx: &mut CrateContext,
|
fn enum_metadata(cx: &mut CrateContext,
|
||||||
enum_type: ty::t,
|
enum_type: ty::t,
|
||||||
enum_def_id: ast::def_id,
|
enum_def_id: ast::def_id,
|
||||||
|
@ -772,142 +769,6 @@ fn enum_metadata(cx: &mut CrateContext,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(stage0)]
|
|
||||||
fn enum_metadata(cx: &mut CrateContext,
|
|
||||||
enum_type: ty::t,
|
|
||||||
enum_def_id: ast::def_id,
|
|
||||||
substs: &ty::substs,
|
|
||||||
span: span)
|
|
||||||
-> DIType {
|
|
||||||
|
|
||||||
let enum_name = ty_to_str(cx.tcx, enum_type);
|
|
||||||
|
|
||||||
// For empty enums there is an early exit. Just describe it as an empty struct with the
|
|
||||||
// appropriate type name
|
|
||||||
if ty::type_is_empty(cx.tcx, enum_type) {
|
|
||||||
return composite_type_metadata(cx, Type::nil(), enum_name, &[], &[], &[], span);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Prepare some data (llvm type, size, align, ...) about the discriminant. This data will be
|
|
||||||
// needed in all of the following cases.
|
|
||||||
let discriminant_llvm_type = Type::enum_discrim(cx);
|
|
||||||
let (discriminant_size, discriminant_align) = size_and_align_of(cx, discriminant_llvm_type);
|
|
||||||
|
|
||||||
assert!(Type::enum_discrim(cx) == cx.int_type);
|
|
||||||
let discriminant_type_metadata = type_metadata(cx, ty::mk_int(), span);
|
|
||||||
|
|
||||||
let variants: &[@ty::VariantInfo] = *ty::enum_variants(cx.tcx, enum_def_id);
|
|
||||||
|
|
||||||
let enumerators_metadata: ~[DIDescriptor] = variants
|
|
||||||
.iter()
|
|
||||||
.transform(|v| {
|
|
||||||
let name: &str = cx.sess.str_of(v.name);
|
|
||||||
let discriminant_value = v.disr_val as c_ulonglong;
|
|
||||||
|
|
||||||
do name.as_c_str |name| {
|
|
||||||
unsafe {
|
|
||||||
llvm::LLVMDIBuilderCreateEnumerator(
|
|
||||||
DIB(cx),
|
|
||||||
name,
|
|
||||||
discriminant_value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
let loc = span_start(cx, span);
|
|
||||||
let file_metadata = file_metadata(cx, loc.file.name);
|
|
||||||
|
|
||||||
let discriminant_type_metadata = do enum_name.as_c_str |enum_name| {
|
|
||||||
unsafe {
|
|
||||||
llvm::LLVMDIBuilderCreateEnumerationType(
|
|
||||||
DIB(cx),
|
|
||||||
file_metadata,
|
|
||||||
enum_name,
|
|
||||||
file_metadata,
|
|
||||||
loc.line as c_uint,
|
|
||||||
bytes_to_bits(discriminant_size),
|
|
||||||
bytes_to_bits(discriminant_align),
|
|
||||||
create_DIArray(DIB(cx), enumerators_metadata),
|
|
||||||
discriminant_type_metadata)
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
if ty::type_is_c_like_enum(cx.tcx, enum_type) {
|
|
||||||
return discriminant_type_metadata;
|
|
||||||
}
|
|
||||||
|
|
||||||
let is_univariant = variants.len() == 1;
|
|
||||||
|
|
||||||
let variants_metadata = do variants.map |&vi| {
|
|
||||||
|
|
||||||
let raw_types: &[ty::t] = vi.args;
|
|
||||||
let arg_types = do raw_types.map |&raw_type| { ty::subst(cx.tcx, substs, raw_type) };
|
|
||||||
|
|
||||||
let mut arg_llvm_types = do arg_types.map |&ty| { type_of::type_of(cx, ty) };
|
|
||||||
let mut arg_names = match vi.arg_names {
|
|
||||||
Some(ref names) => do names.map |ident| { cx.sess.str_of(*ident).to_owned() },
|
|
||||||
None => do arg_types.map |_| { ~"" }
|
|
||||||
};
|
|
||||||
|
|
||||||
let mut arg_metadata = do arg_types.map |&ty| { type_metadata(cx, ty, span) };
|
|
||||||
|
|
||||||
if !is_univariant {
|
|
||||||
arg_llvm_types.insert(0, discriminant_llvm_type);
|
|
||||||
arg_names.insert(0, ~"");
|
|
||||||
arg_metadata.insert(0, discriminant_type_metadata);
|
|
||||||
}
|
|
||||||
|
|
||||||
let variant_llvm_type = Type::struct_(arg_llvm_types, false);
|
|
||||||
let (variant_type_size, variant_type_align) = size_and_align_of(cx, variant_llvm_type);
|
|
||||||
|
|
||||||
let variant_type_metadata = composite_type_metadata(
|
|
||||||
cx,
|
|
||||||
variant_llvm_type,
|
|
||||||
&"",
|
|
||||||
arg_llvm_types,
|
|
||||||
arg_names,
|
|
||||||
arg_metadata,
|
|
||||||
span);
|
|
||||||
|
|
||||||
do "".as_c_str |name| {
|
|
||||||
unsafe {
|
|
||||||
llvm::LLVMDIBuilderCreateMemberType(
|
|
||||||
DIB(cx),
|
|
||||||
file_metadata,
|
|
||||||
name,
|
|
||||||
file_metadata,
|
|
||||||
loc.line as c_uint,
|
|
||||||
bytes_to_bits(variant_type_size),
|
|
||||||
bytes_to_bits(variant_type_align),
|
|
||||||
bytes_to_bits(0),
|
|
||||||
0,
|
|
||||||
variant_type_metadata)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
let enum_llvm_type = type_of::type_of(cx, enum_type);
|
|
||||||
let (enum_type_size, enum_type_align) = size_and_align_of(cx, enum_llvm_type);
|
|
||||||
|
|
||||||
return do enum_name.as_c_str |enum_name| {
|
|
||||||
unsafe {
|
|
||||||
llvm::LLVMDIBuilderCreateUnionType(
|
|
||||||
DIB(cx),
|
|
||||||
file_metadata,
|
|
||||||
enum_name,
|
|
||||||
file_metadata,
|
|
||||||
loc.line as c_uint,
|
|
||||||
bytes_to_bits(enum_type_size),
|
|
||||||
bytes_to_bits(enum_type_align),
|
|
||||||
0, // Flags
|
|
||||||
create_DIArray(DIB(cx), variants_metadata),
|
|
||||||
0) // RuntimeLang
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/// Creates debug information for a composite type, that is, anything that results in a LLVM struct.
|
/// Creates debug information for a composite type, that is, anything that results in a LLVM struct.
|
||||||
///
|
///
|
||||||
/// Examples of Rust types to use this are: structs, tuples, boxes, vecs, and enums.
|
/// Examples of Rust types to use this are: structs, tuples, boxes, vecs, and enums.
|
||||||
|
|
|
@ -21,7 +21,6 @@ A dynamic, mutable location.
|
||||||
Similar to a mutable option type, but friendlier.
|
Similar to a mutable option type, but friendlier.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#[mutable] // XXX remove after snap
|
|
||||||
#[no_freeze]
|
#[no_freeze]
|
||||||
#[deriving(Clone, DeepClone, Eq)]
|
#[deriving(Clone, DeepClone, Eq)]
|
||||||
#[allow(missing_doc)]
|
#[allow(missing_doc)]
|
||||||
|
|
|
@ -73,19 +73,6 @@ fn debug_mem() -> bool {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
#[cfg(not(stage0))]
|
|
||||||
unsafe fn call_drop_glue(tydesc: *TyDesc, data: *i8) {
|
|
||||||
// This function should be inlined when stage0 is gone
|
|
||||||
((*tydesc).drop_glue)(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
#[cfg(stage0)]
|
|
||||||
unsafe fn call_drop_glue(tydesc: *TyDesc, data: *i8) {
|
|
||||||
((*tydesc).drop_glue)(0 as **TyDesc, data);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Destroys all managed memory (i.e. @ boxes) held by the current task.
|
/// Destroys all managed memory (i.e. @ boxes) held by the current task.
|
||||||
pub unsafe fn annihilate() {
|
pub unsafe fn annihilate() {
|
||||||
use rt::local_heap::local_free;
|
use rt::local_heap::local_free;
|
||||||
|
@ -128,7 +115,7 @@ pub unsafe fn annihilate() {
|
||||||
if !uniq {
|
if !uniq {
|
||||||
let tydesc: *TyDesc = transmute((*box).header.type_desc);
|
let tydesc: *TyDesc = transmute((*box).header.type_desc);
|
||||||
let data = transmute(&(*box).data);
|
let data = transmute(&(*box).data);
|
||||||
call_drop_glue(tydesc, data);
|
((*tydesc).drop_glue)(data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,18 +23,11 @@ pub struct Handler<T, U> {
|
||||||
prev: Option<@Handler<T, U>>,
|
prev: Option<@Handler<T, U>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(stage0)]
|
|
||||||
pub struct Condition<'self, T, U> {
|
|
||||||
name: &'static str,
|
|
||||||
key: local_data::Key<'self, @Handler<T, U>>
|
|
||||||
}
|
|
||||||
#[cfg(not(stage0))]
|
|
||||||
pub struct Condition<T, U> {
|
pub struct Condition<T, U> {
|
||||||
name: &'static str,
|
name: &'static str,
|
||||||
key: local_data::Key<@Handler<T, U>>
|
key: local_data::Key<@Handler<T, U>>
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(stage0))]
|
|
||||||
impl<T, U> Condition<T, U> {
|
impl<T, U> Condition<T, U> {
|
||||||
pub fn trap<'a>(&'a self, h: &'a fn(T) -> U) -> Trap<'a, T, U> {
|
pub fn trap<'a>(&'a self, h: &'a fn(T) -> U) -> Trap<'a, T, U> {
|
||||||
unsafe {
|
unsafe {
|
||||||
|
@ -73,56 +66,7 @@ impl<T, U> Condition<T, U> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#[cfg(stage0)]
|
|
||||||
impl<'self, T, U> Condition<'self, T, U> {
|
|
||||||
pub fn trap<'a>(&'a self, h: &'a fn(T) -> U) -> Trap<'a, T, U> {
|
|
||||||
unsafe {
|
|
||||||
let p : *RustClosure = ::cast::transmute(&h);
|
|
||||||
let prev = local_data::get(::cast::unsafe_copy(&self.key),
|
|
||||||
|k| k.map(|&x| *x));
|
|
||||||
let h = @Handler { handle: *p, prev: prev };
|
|
||||||
Trap { cond: self, handler: h }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn raise(&self, t: T) -> U {
|
|
||||||
let msg = fmt!("Unhandled condition: %s: %?", self.name, t);
|
|
||||||
self.raise_default(t, || fail!(msg.clone()))
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn raise_default(&self, t: T, default: &fn() -> U) -> U {
|
|
||||||
unsafe {
|
|
||||||
match local_data::pop(::cast::unsafe_copy(&self.key)) {
|
|
||||||
None => {
|
|
||||||
debug!("Condition.raise: found no handler");
|
|
||||||
default()
|
|
||||||
}
|
|
||||||
Some(handler) => {
|
|
||||||
debug!("Condition.raise: found handler");
|
|
||||||
match handler.prev {
|
|
||||||
None => {}
|
|
||||||
Some(hp) => {
|
|
||||||
local_data::set(::cast::unsafe_copy(&self.key),
|
|
||||||
hp)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
let handle : &fn(T) -> U =
|
|
||||||
::cast::transmute(handler.handle);
|
|
||||||
let u = handle(t);
|
|
||||||
local_data::set(::cast::unsafe_copy(&self.key), handler);
|
|
||||||
u
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(stage0)]
|
|
||||||
struct Trap<'self, T, U> {
|
|
||||||
cond: &'self Condition<'self, T, U>,
|
|
||||||
handler: @Handler<T, U>
|
|
||||||
}
|
|
||||||
#[cfg(not(stage0))]
|
|
||||||
struct Trap<'self, T, U> {
|
struct Trap<'self, T, U> {
|
||||||
cond: &'self Condition<T, U>,
|
cond: &'self Condition<T, U>,
|
||||||
handler: @Handler<T, U>
|
handler: @Handler<T, U>
|
||||||
|
@ -137,11 +81,6 @@ impl<'self, T, U> Trap<'self, T, U> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(stage0)]
|
|
||||||
struct Guard<'self, T, U> {
|
|
||||||
cond: &'self Condition<'self, T, U>
|
|
||||||
}
|
|
||||||
#[cfg(not(stage0))]
|
|
||||||
struct Guard<'self, T, U> {
|
struct Guard<'self, T, U> {
|
||||||
cond: &'self Condition<T, U>
|
cond: &'self Condition<T, U>
|
||||||
}
|
}
|
||||||
|
|
|
@ -317,19 +317,6 @@ fn expect_sentinel() -> bool { true }
|
||||||
#[cfg(nogc)]
|
#[cfg(nogc)]
|
||||||
fn expect_sentinel() -> bool { false }
|
fn expect_sentinel() -> bool { false }
|
||||||
|
|
||||||
#[inline]
|
|
||||||
#[cfg(not(stage0))]
|
|
||||||
unsafe fn call_drop_glue(tydesc: *TyDesc, data: *i8) {
|
|
||||||
// This function should be inlined when stage0 is gone
|
|
||||||
((*tydesc).drop_glue)(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
#[cfg(stage0)]
|
|
||||||
unsafe fn call_drop_glue(tydesc: *TyDesc, data: *i8) {
|
|
||||||
((*tydesc).drop_glue)(0 as **TyDesc, data);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Entry point for GC-based cleanup. Walks stack looking for exchange
|
// Entry point for GC-based cleanup. Walks stack looking for exchange
|
||||||
// heap and stack allocations requiring drop, and runs all
|
// heap and stack allocations requiring drop, and runs all
|
||||||
// destructors.
|
// destructors.
|
||||||
|
@ -373,7 +360,7 @@ pub fn cleanup_stack_for_failure() {
|
||||||
// FIXME #4420: Destroy this box
|
// FIXME #4420: Destroy this box
|
||||||
// FIXME #4330: Destroy this box
|
// FIXME #4330: Destroy this box
|
||||||
} else {
|
} else {
|
||||||
call_drop_glue(tydesc, *root as *i8);
|
((*tydesc).drop_glue)(*root as *i8);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,31 +29,11 @@ The 2 kinds are
|
||||||
|
|
||||||
#[allow(missing_doc)];
|
#[allow(missing_doc)];
|
||||||
|
|
||||||
#[cfg(stage0)]
|
|
||||||
#[lang="copy"]
|
|
||||||
pub trait Copy {
|
|
||||||
// Empty.
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(stage0)]
|
|
||||||
#[lang="owned"]
|
|
||||||
pub trait Send {
|
|
||||||
// empty.
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(not(stage0))]
|
|
||||||
#[lang="send"]
|
#[lang="send"]
|
||||||
pub trait Send {
|
pub trait Send {
|
||||||
// empty.
|
// empty.
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(stage0)]
|
|
||||||
#[lang="const"]
|
|
||||||
pub trait Freeze {
|
|
||||||
// empty.
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(not(stage0))]
|
|
||||||
#[lang="freeze"]
|
#[lang="freeze"]
|
||||||
pub trait Freeze {
|
pub trait Freeze {
|
||||||
// empty.
|
// empty.
|
||||||
|
|
|
@ -56,10 +56,7 @@ use task::local_data_priv::*;
|
||||||
* sections to ensure that each value of the `Key` type points to a unique
|
* sections to ensure that each value of the `Key` type points to a unique
|
||||||
* location.
|
* location.
|
||||||
*/
|
*/
|
||||||
#[cfg(not(stage0))]
|
|
||||||
pub type Key<T> = &'static KeyValue<T>;
|
pub type Key<T> = &'static KeyValue<T>;
|
||||||
#[cfg(stage0)]
|
|
||||||
pub type Key<'self,T> = &'self fn(v: T);
|
|
||||||
|
|
||||||
pub enum KeyValue<T> { Key }
|
pub enum KeyValue<T> { Key }
|
||||||
|
|
||||||
|
@ -67,73 +64,37 @@ pub enum KeyValue<T> { Key }
|
||||||
* Remove a task-local data value from the table, returning the
|
* Remove a task-local data value from the table, returning the
|
||||||
* reference that was originally created to insert it.
|
* reference that was originally created to insert it.
|
||||||
*/
|
*/
|
||||||
#[cfg(stage0)]
|
|
||||||
pub fn pop<T: 'static>(key: Key<@T>) -> Option<@T> {
|
|
||||||
unsafe { local_pop(Handle::new(), key) }
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Remove a task-local data value from the table, returning the
|
|
||||||
* reference that was originally created to insert it.
|
|
||||||
*/
|
|
||||||
#[cfg(not(stage0))]
|
|
||||||
pub fn pop<T: 'static>(key: Key<T>) -> Option<T> {
|
pub fn pop<T: 'static>(key: Key<T>) -> Option<T> {
|
||||||
unsafe { local_pop(Handle::new(), key) }
|
unsafe { local_pop(Handle::new(), key) }
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve a task-local data value. It will also be kept alive in the
|
* Retrieve a task-local data value. It will also be kept alive in the
|
||||||
* table until explicitly removed.
|
* table until explicitly removed.
|
||||||
*/
|
*/
|
||||||
#[cfg(stage0)]
|
|
||||||
pub fn get<T: 'static, U>(key: Key<@T>, f: &fn(Option<&@T>) -> U) -> U {
|
|
||||||
unsafe { local_get(Handle::new(), key, f) }
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Retrieve a task-local data value. It will also be kept alive in the
|
|
||||||
* table until explicitly removed.
|
|
||||||
*/
|
|
||||||
#[cfg(not(stage0))]
|
|
||||||
pub fn get<T: 'static, U>(key: Key<T>, f: &fn(Option<&T>) -> U) -> U {
|
pub fn get<T: 'static, U>(key: Key<T>, f: &fn(Option<&T>) -> U) -> U {
|
||||||
unsafe { local_get(Handle::new(), key, f) }
|
unsafe { local_get(Handle::new(), key, f) }
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve a mutable borrowed pointer to a task-local data value.
|
* Retrieve a mutable borrowed pointer to a task-local data value.
|
||||||
*/
|
*/
|
||||||
#[cfg(not(stage0))]
|
|
||||||
pub fn get_mut<T: 'static, U>(key: Key<T>, f: &fn(Option<&mut T>) -> U) -> U {
|
pub fn get_mut<T: 'static, U>(key: Key<T>, f: &fn(Option<&mut T>) -> U) -> U {
|
||||||
unsafe { local_get_mut(Handle::new(), key, f) }
|
unsafe { local_get_mut(Handle::new(), key, f) }
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Store a value in task-local data. If this key already has a value,
|
* Store a value in task-local data. If this key already has a value,
|
||||||
* that value is overwritten (and its destructor is run).
|
* that value is overwritten (and its destructor is run).
|
||||||
*/
|
*/
|
||||||
#[cfg(stage0)]
|
|
||||||
pub fn set<T: 'static>(key: Key<@T>, data: @T) {
|
|
||||||
unsafe { local_set(Handle::new(), key, data) }
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Store a value in task-local data. If this key already has a value,
|
|
||||||
* that value is overwritten (and its destructor is run).
|
|
||||||
*/
|
|
||||||
#[cfg(not(stage0))]
|
|
||||||
pub fn set<T: 'static>(key: Key<T>, data: T) {
|
pub fn set<T: 'static>(key: Key<T>, data: T) {
|
||||||
unsafe { local_set(Handle::new(), key, data) }
|
unsafe { local_set(Handle::new(), key, data) }
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Modify a task-local data value. If the function returns 'None', the
|
* Modify a task-local data value. If the function returns 'None', the
|
||||||
* data is removed (and its reference dropped).
|
* data is removed (and its reference dropped).
|
||||||
*/
|
*/
|
||||||
#[cfg(stage0)]
|
|
||||||
pub fn modify<T: 'static>(key: Key<@T>, f: &fn(Option<@T>) -> Option<@T>) {
|
|
||||||
match f(pop(key)) {
|
|
||||||
Some(next) => { set(key, next); }
|
|
||||||
None => {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Modify a task-local data value. If the function returns 'None', the
|
|
||||||
* data is removed (and its reference dropped).
|
|
||||||
*/
|
|
||||||
#[cfg(not(stage0))]
|
|
||||||
pub fn modify<T: 'static>(key: Key<T>, f: &fn(Option<T>) -> Option<T>) {
|
pub fn modify<T: 'static>(key: Key<T>, f: &fn(Option<T>) -> Option<T>) {
|
||||||
unsafe {
|
unsafe {
|
||||||
match f(pop(::cast::unsafe_copy(&key))) {
|
match f(pop(::cast::unsafe_copy(&key))) {
|
||||||
|
|
|
@ -1237,9 +1237,6 @@ struct OverriddenArgs {
|
||||||
val: ~[~str]
|
val: ~[~str]
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(stage0)]
|
|
||||||
fn overridden_arg_key(_v: @OverriddenArgs) {}
|
|
||||||
#[cfg(not(stage0))]
|
|
||||||
static overridden_arg_key: local_data::Key<@OverriddenArgs> = &local_data::Key;
|
static overridden_arg_key: local_data::Key<@OverriddenArgs> = &local_data::Key;
|
||||||
|
|
||||||
/// Returns the arguments which this program was started with (normally passed
|
/// Returns the arguments which this program was started with (normally passed
|
||||||
|
|
|
@ -852,9 +852,6 @@ pub fn seed() -> ~[u8] {
|
||||||
}
|
}
|
||||||
|
|
||||||
// used to make space in TLS for a random number generator
|
// used to make space in TLS for a random number generator
|
||||||
#[cfg(stage0)]
|
|
||||||
fn tls_rng_state(_v: @@mut IsaacRng) {}
|
|
||||||
#[cfg(not(stage0))]
|
|
||||||
static tls_rng_state: local_data::Key<@@mut IsaacRng> = &local_data::Key;
|
static tls_rng_state: local_data::Key<@@mut IsaacRng> = &local_data::Key;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -16,9 +16,6 @@ Runtime type reflection
|
||||||
|
|
||||||
#[allow(missing_doc)];
|
#[allow(missing_doc)];
|
||||||
|
|
||||||
#[cfg(stage0)]
|
|
||||||
use intrinsic::{Opaque, TyDesc, TyVisitor};
|
|
||||||
#[cfg(not(stage0))]
|
|
||||||
use unstable::intrinsics::{Opaque, TyDesc, TyVisitor};
|
use unstable::intrinsics::{Opaque, TyDesc, TyVisitor};
|
||||||
use libc::c_void;
|
use libc::c_void;
|
||||||
use sys;
|
use sys;
|
||||||
|
@ -197,14 +194,6 @@ impl<V:TyVisitor + MovePtr> TyVisitor for MovePtrAdaptor<V> {
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(stage0)]
|
|
||||||
fn visit_str(&self) -> bool {
|
|
||||||
self.align_to::<~str>();
|
|
||||||
if ! self.inner.visit_str() { return false; }
|
|
||||||
self.bump_past::<~str>();
|
|
||||||
true
|
|
||||||
}
|
|
||||||
|
|
||||||
fn visit_estr_box(&self) -> bool {
|
fn visit_estr_box(&self) -> bool {
|
||||||
self.align_to::<@str>();
|
self.align_to::<@str>();
|
||||||
if ! self.inner.visit_estr_box() { return false; }
|
if ! self.inner.visit_estr_box() { return false; }
|
||||||
|
@ -249,7 +238,6 @@ impl<V:TyVisitor + MovePtr> TyVisitor for MovePtrAdaptor<V> {
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(stage0))]
|
|
||||||
fn visit_uniq_managed(&self, mtbl: uint, inner: *TyDesc) -> bool {
|
fn visit_uniq_managed(&self, mtbl: uint, inner: *TyDesc) -> bool {
|
||||||
self.align_to::<~u8>();
|
self.align_to::<~u8>();
|
||||||
if ! self.inner.visit_uniq_managed(mtbl, inner) { return false; }
|
if ! self.inner.visit_uniq_managed(mtbl, inner) { return false; }
|
||||||
|
@ -298,7 +286,6 @@ impl<V:TyVisitor + MovePtr> TyVisitor for MovePtrAdaptor<V> {
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(stage0))]
|
|
||||||
fn visit_evec_uniq_managed(&self, mtbl: uint, inner: *TyDesc) -> bool {
|
fn visit_evec_uniq_managed(&self, mtbl: uint, inner: *TyDesc) -> bool {
|
||||||
self.align_to::<~[@u8]>();
|
self.align_to::<~[@u8]>();
|
||||||
if ! self.inner.visit_evec_uniq_managed(mtbl, inner) { return false; }
|
if ! self.inner.visit_evec_uniq_managed(mtbl, inner) { return false; }
|
||||||
|
|
|
@ -31,9 +31,6 @@ use to_str::ToStr;
|
||||||
use vec::raw::{VecRepr, SliceRepr};
|
use vec::raw::{VecRepr, SliceRepr};
|
||||||
use vec;
|
use vec;
|
||||||
use vec::{OwnedVector, UnboxedVecRepr};
|
use vec::{OwnedVector, UnboxedVecRepr};
|
||||||
#[cfg(stage0)]
|
|
||||||
use intrinsic::{Opaque, TyDesc, TyVisitor, get_tydesc, visit_tydesc};
|
|
||||||
#[cfg(not(stage0))]
|
|
||||||
use unstable::intrinsics::{Opaque, TyDesc, TyVisitor, get_tydesc, visit_tydesc};
|
use unstable::intrinsics::{Opaque, TyDesc, TyVisitor, get_tydesc, visit_tydesc};
|
||||||
|
|
||||||
#[cfg(test)] use io;
|
#[cfg(test)] use io;
|
||||||
|
@ -267,10 +264,6 @@ impl TyVisitor for ReprVisitor {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Type no longer exists, vestigial function.
|
|
||||||
#[cfg(stage0)]
|
|
||||||
fn visit_str(&self) -> bool { fail!(); }
|
|
||||||
|
|
||||||
fn visit_estr_box(&self) -> bool {
|
fn visit_estr_box(&self) -> bool {
|
||||||
do self.get::<@str> |s| {
|
do self.get::<@str> |s| {
|
||||||
self.writer.write_char('@');
|
self.writer.write_char('@');
|
||||||
|
@ -309,7 +302,6 @@ impl TyVisitor for ReprVisitor {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(stage0))]
|
|
||||||
fn visit_uniq_managed(&self, _mtbl: uint, inner: *TyDesc) -> bool {
|
fn visit_uniq_managed(&self, _mtbl: uint, inner: *TyDesc) -> bool {
|
||||||
self.writer.write_char('~');
|
self.writer.write_char('~');
|
||||||
do self.get::<&managed::raw::BoxRepr> |b| {
|
do self.get::<&managed::raw::BoxRepr> |b| {
|
||||||
|
@ -351,15 +343,6 @@ impl TyVisitor for ReprVisitor {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(stage0)]
|
|
||||||
fn visit_evec_uniq(&self, mtbl: uint, inner: *TyDesc) -> bool {
|
|
||||||
do self.get::<&VecRepr> |b| {
|
|
||||||
self.writer.write_char('~');
|
|
||||||
self.write_unboxed_vec_repr(mtbl, &b.unboxed, inner);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(not(stage0))]
|
|
||||||
fn visit_evec_uniq(&self, mtbl: uint, inner: *TyDesc) -> bool {
|
fn visit_evec_uniq(&self, mtbl: uint, inner: *TyDesc) -> bool {
|
||||||
do self.get::<&UnboxedVecRepr> |b| {
|
do self.get::<&UnboxedVecRepr> |b| {
|
||||||
self.writer.write_char('~');
|
self.writer.write_char('~');
|
||||||
|
@ -367,7 +350,6 @@ impl TyVisitor for ReprVisitor {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(stage0))]
|
|
||||||
fn visit_evec_uniq_managed(&self, mtbl: uint, inner: *TyDesc) -> bool {
|
fn visit_evec_uniq_managed(&self, mtbl: uint, inner: *TyDesc) -> bool {
|
||||||
do self.get::<&VecRepr> |b| {
|
do self.get::<&VecRepr> |b| {
|
||||||
self.writer.write_char('~');
|
self.writer.write_char('~');
|
||||||
|
@ -563,7 +545,6 @@ impl TyVisitor for ReprVisitor {
|
||||||
fn visit_self(&self) -> bool { true }
|
fn visit_self(&self) -> bool { true }
|
||||||
fn visit_type(&self) -> bool { true }
|
fn visit_type(&self) -> bool { true }
|
||||||
|
|
||||||
#[cfg(not(stage0))]
|
|
||||||
fn visit_opaque_box(&self) -> bool {
|
fn visit_opaque_box(&self) -> bool {
|
||||||
self.writer.write_char('@');
|
self.writer.write_char('@');
|
||||||
do self.get::<&managed::raw::BoxRepr> |b| {
|
do self.get::<&managed::raw::BoxRepr> |b| {
|
||||||
|
@ -571,16 +552,6 @@ impl TyVisitor for ReprVisitor {
|
||||||
self.visit_ptr_inner(p, b.header.type_desc);
|
self.visit_ptr_inner(p, b.header.type_desc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#[cfg(stage0)]
|
|
||||||
fn visit_opaque_box(&self) -> bool {
|
|
||||||
self.writer.write_char('@');
|
|
||||||
do self.get::<&managed::raw::BoxRepr> |b| {
|
|
||||||
let p = ptr::to_unsafe_ptr(&b.data) as *c_void;
|
|
||||||
unsafe {
|
|
||||||
self.visit_ptr_inner(p, transmute(b.header.type_desc));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Type no longer exists, vestigial function.
|
// Type no longer exists, vestigial function.
|
||||||
fn visit_constr(&self, _inner: *TyDesc) -> bool { fail!(); }
|
fn visit_constr(&self, _inner: *TyDesc) -> bool { fail!(); }
|
||||||
|
|
|
@ -56,28 +56,8 @@ pub unsafe fn realloc_raw(ptr: *mut c_void, size: uint) -> *mut c_void {
|
||||||
p
|
p
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME #4942: Make these signatures agree with exchange_alloc's signatures
|
|
||||||
#[cfg(stage0, not(test))]
|
|
||||||
#[lang="exchange_malloc"]
|
|
||||||
#[inline]
|
|
||||||
pub unsafe fn exchange_malloc(td: *c_char, size: uintptr_t) -> *c_char {
|
|
||||||
let td = td as *TyDesc;
|
|
||||||
let size = size as uint;
|
|
||||||
|
|
||||||
assert!(td.is_not_null());
|
|
||||||
|
|
||||||
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.ref_count = -1;
|
|
||||||
(*box).header.type_desc = td;
|
|
||||||
|
|
||||||
box as *c_char
|
|
||||||
}
|
|
||||||
|
|
||||||
/// The allocator for unique pointers without contained managed pointers.
|
/// The allocator for unique pointers without contained managed pointers.
|
||||||
#[cfg(not(stage0), not(test))]
|
#[cfg(not(test))]
|
||||||
#[lang="exchange_malloc"]
|
#[lang="exchange_malloc"]
|
||||||
#[inline]
|
#[inline]
|
||||||
pub unsafe fn exchange_malloc(size: uintptr_t) -> *c_char {
|
pub unsafe fn exchange_malloc(size: uintptr_t) -> *c_char {
|
||||||
|
|
|
@ -1006,19 +1006,6 @@ pub mod raw {
|
||||||
|
|
||||||
/// Sets the length of the string and adds the null terminator
|
/// Sets the length of the string and adds the null terminator
|
||||||
#[inline]
|
#[inline]
|
||||||
#[cfg(stage0)]
|
|
||||||
pub unsafe fn set_len(v: &mut ~str, new_len: uint) {
|
|
||||||
let v: **mut vec::raw::VecRepr = cast::transmute(v);
|
|
||||||
let repr: *mut vec::raw::VecRepr = *v;
|
|
||||||
(*repr).unboxed.fill = new_len + 1u;
|
|
||||||
let null = ptr::mut_offset(cast::transmute(&((*repr).unboxed.data)),
|
|
||||||
new_len);
|
|
||||||
*null = 0u8;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Sets the length of the string and adds the null terminator
|
|
||||||
#[inline]
|
|
||||||
#[cfg(not(stage0))]
|
|
||||||
pub unsafe fn set_len(v: &mut ~str, new_len: uint) {
|
pub unsafe fn set_len(v: &mut ~str, new_len: uint) {
|
||||||
let v: **mut vec::UnboxedVecRepr = cast::transmute(v);
|
let v: **mut vec::UnboxedVecRepr = cast::transmute(v);
|
||||||
let repr: *mut vec::UnboxedVecRepr = *v;
|
let repr: *mut vec::UnboxedVecRepr = *v;
|
||||||
|
|
|
@ -1,229 +0,0 @@
|
||||||
// Copyright 2012 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.
|
|
||||||
|
|
||||||
#[allow(missing_doc)];
|
|
||||||
|
|
||||||
use cast;
|
|
||||||
use cmp::Eq;
|
|
||||||
use libc;
|
|
||||||
use local_data;
|
|
||||||
use prelude::*;
|
|
||||||
use sys;
|
|
||||||
use task::rt;
|
|
||||||
|
|
||||||
use super::rt::rust_task;
|
|
||||||
use rt::task::{Task, LocalStorage};
|
|
||||||
|
|
||||||
pub enum Handle {
|
|
||||||
OldHandle(*rust_task),
|
|
||||||
NewHandle(*mut LocalStorage)
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Handle {
|
|
||||||
pub fn new() -> Handle {
|
|
||||||
use rt::{context, OldTaskContext};
|
|
||||||
use rt::local::Local;
|
|
||||||
unsafe {
|
|
||||||
match context() {
|
|
||||||
OldTaskContext => {
|
|
||||||
OldHandle(rt::rust_get_task())
|
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
let task = Local::unsafe_borrow::<Task>();
|
|
||||||
NewHandle(&mut (*task).storage)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub trait LocalData { }
|
|
||||||
impl<T: 'static> LocalData for @T { }
|
|
||||||
|
|
||||||
impl Eq for @LocalData {
|
|
||||||
fn eq(&self, other: &@LocalData) -> bool {
|
|
||||||
unsafe {
|
|
||||||
let ptr_a: &(uint, uint) = cast::transmute(self);
|
|
||||||
let ptr_b: &(uint, uint) = cast::transmute(other);
|
|
||||||
return ptr_a == ptr_b;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fn ne(&self, other: &@LocalData) -> bool { !(*self).eq(other) }
|
|
||||||
}
|
|
||||||
|
|
||||||
// If TLS is used heavily in future, this could be made more efficient with a
|
|
||||||
// proper map.
|
|
||||||
type TaskLocalElement = (*libc::c_void, *libc::c_void, @LocalData);
|
|
||||||
// Has to be a pointer at outermost layer; the foreign call returns void *.
|
|
||||||
type TaskLocalMap = ~[Option<TaskLocalElement>];
|
|
||||||
|
|
||||||
fn cleanup_task_local_map(map_ptr: *libc::c_void) {
|
|
||||||
unsafe {
|
|
||||||
assert!(!map_ptr.is_null());
|
|
||||||
// Get and keep the single reference that was created at the
|
|
||||||
// beginning.
|
|
||||||
let _map: TaskLocalMap = cast::transmute(map_ptr);
|
|
||||||
// All local_data will be destroyed along with the map.
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Gets the map from the runtime. Lazily initialises if not done so already.
|
|
||||||
unsafe fn get_local_map(handle: Handle) -> &mut TaskLocalMap {
|
|
||||||
match handle {
|
|
||||||
OldHandle(task) => get_task_local_map(task),
|
|
||||||
NewHandle(local_storage) => get_newsched_local_map(local_storage)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
unsafe fn get_task_local_map(task: *rust_task) -> &mut TaskLocalMap {
|
|
||||||
|
|
||||||
extern fn cleanup_task_local_map_extern_cb(map_ptr: *libc::c_void) {
|
|
||||||
cleanup_task_local_map(map_ptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Relies on the runtime initialising the pointer to null.
|
|
||||||
// Note: the map is an owned pointer and is "owned" by TLS. It is moved
|
|
||||||
// into the tls slot for this task, and then mutable loans are taken from
|
|
||||||
// this slot to modify the map.
|
|
||||||
let map_ptr = rt::rust_get_task_local_data(task);
|
|
||||||
if (*map_ptr).is_null() {
|
|
||||||
// First time TLS is used, create a new map and set up the necessary
|
|
||||||
// TLS information for its safe destruction
|
|
||||||
let map: TaskLocalMap = ~[];
|
|
||||||
*map_ptr = cast::transmute(map);
|
|
||||||
rt::rust_task_local_data_atexit(task, cleanup_task_local_map_extern_cb);
|
|
||||||
}
|
|
||||||
return cast::transmute(map_ptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
unsafe fn get_newsched_local_map(local: *mut LocalStorage) -> &mut TaskLocalMap {
|
|
||||||
// This is based on the same idea as the oldsched code above.
|
|
||||||
match &mut *local {
|
|
||||||
// If the at_exit function is already set, then we just need to take a
|
|
||||||
// loan out on the TLS map stored inside
|
|
||||||
&LocalStorage(ref mut map_ptr, Some(_)) => {
|
|
||||||
assert!(map_ptr.is_not_null());
|
|
||||||
return cast::transmute(map_ptr);
|
|
||||||
}
|
|
||||||
// If this is the first time we've accessed TLS, perform similar
|
|
||||||
// actions to the oldsched way of doing things.
|
|
||||||
&LocalStorage(ref mut map_ptr, ref mut at_exit) => {
|
|
||||||
assert!(map_ptr.is_null());
|
|
||||||
assert!(at_exit.is_none());
|
|
||||||
let map: TaskLocalMap = ~[];
|
|
||||||
*map_ptr = cast::transmute(map);
|
|
||||||
*at_exit = Some(cleanup_task_local_map);
|
|
||||||
return cast::transmute(map_ptr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
unsafe fn key_to_key_value<T: 'static>(key: local_data::Key<@T>) -> *libc::c_void {
|
|
||||||
let pair: sys::Closure = cast::transmute(key);
|
|
||||||
return pair.code as *libc::c_void;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If returning Some(..), returns with @T with the map's reference. Careful!
|
|
||||||
unsafe fn local_data_lookup<T: 'static>(
|
|
||||||
map: &mut TaskLocalMap, key: local_data::Key<@T>)
|
|
||||||
-> Option<(uint, *libc::c_void)> {
|
|
||||||
|
|
||||||
let key_value = key_to_key_value(key);
|
|
||||||
for map.iter().enumerate().advance |(i, entry)| {
|
|
||||||
match *entry {
|
|
||||||
Some((k, data, _)) if k == key_value => { return Some((i, data)); }
|
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsafe fn local_get_helper<T: 'static>(
|
|
||||||
handle: Handle, key: local_data::Key<@T>,
|
|
||||||
do_pop: bool) -> Option<@T> {
|
|
||||||
|
|
||||||
let map = get_local_map(handle);
|
|
||||||
// Interpreturn our findings from the map
|
|
||||||
do local_data_lookup(map, key).map |result| {
|
|
||||||
// A reference count magically appears on 'data' out of thin air. It
|
|
||||||
// was referenced in the local_data box, though, not here, so before
|
|
||||||
// overwriting the local_data_box we need to give an extra reference.
|
|
||||||
// We must also give an extra reference when not removing.
|
|
||||||
let (index, data_ptr) = *result;
|
|
||||||
let data: @T = cast::transmute(data_ptr);
|
|
||||||
cast::bump_box_refcount(data);
|
|
||||||
if do_pop {
|
|
||||||
map[index] = None;
|
|
||||||
}
|
|
||||||
data
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
pub unsafe fn local_pop<T: 'static>(
|
|
||||||
handle: Handle,
|
|
||||||
key: local_data::Key<@T>) -> Option<@T> {
|
|
||||||
|
|
||||||
local_get_helper(handle, key, true)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub unsafe fn local_get<T: 'static, U>(
|
|
||||||
handle: Handle,
|
|
||||||
key: local_data::Key<@T>,
|
|
||||||
f: &fn(Option<&@T>) -> U) -> U {
|
|
||||||
|
|
||||||
match local_get_helper(handle, key, false) {
|
|
||||||
Some(ref x) => f(Some(x)),
|
|
||||||
None => f(None)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub unsafe fn local_set<T: 'static>(
|
|
||||||
handle: Handle, key: local_data::Key<@T>, data: @T) {
|
|
||||||
|
|
||||||
let map = get_local_map(handle);
|
|
||||||
// Store key+data as *voids. Data is invisibly referenced once; key isn't.
|
|
||||||
let keyval = key_to_key_value(key);
|
|
||||||
// We keep the data in two forms: one as an unsafe pointer, so we can get
|
|
||||||
// it back by casting; another in an existential box, so the reference we
|
|
||||||
// own on it can be dropped when the box is destroyed. The unsafe pointer
|
|
||||||
// does not have a reference associated with it, so it may become invalid
|
|
||||||
// when the box is destroyed.
|
|
||||||
let data_ptr = *cast::transmute::<&@T, &*libc::c_void>(&data);
|
|
||||||
let data_box = @data as @LocalData;
|
|
||||||
// Construct new entry to store in the map.
|
|
||||||
let new_entry = Some((keyval, data_ptr, data_box));
|
|
||||||
// Find a place to put it.
|
|
||||||
match local_data_lookup(map, key) {
|
|
||||||
Some((index, _old_data_ptr)) => {
|
|
||||||
// Key already had a value set, _old_data_ptr, whose reference
|
|
||||||
// will get dropped when the local_data box is overwritten.
|
|
||||||
map[index] = new_entry;
|
|
||||||
}
|
|
||||||
None => {
|
|
||||||
// Find an empty slot. If not, grow the vector.
|
|
||||||
match map.iter().position(|x| x.is_none()) {
|
|
||||||
Some(empty_index) => { map[empty_index] = new_entry; }
|
|
||||||
None => { map.push(new_entry); }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub unsafe fn local_modify<T: 'static>(
|
|
||||||
handle: Handle, key: local_data::Key<@T>,
|
|
||||||
modify_fn: &fn(Option<@T>) -> Option<@T>) {
|
|
||||||
|
|
||||||
// Could be more efficient by doing the lookup work, but this is easy.
|
|
||||||
let newdata = modify_fn(local_pop(handle, key));
|
|
||||||
if newdata.is_some() {
|
|
||||||
local_set(handle, key, newdata.unwrap());
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -54,10 +54,6 @@ use util;
|
||||||
#[cfg(test)] use ptr;
|
#[cfg(test)] use ptr;
|
||||||
#[cfg(test)] use task;
|
#[cfg(test)] use task;
|
||||||
|
|
||||||
#[cfg(stage0)]
|
|
||||||
#[path="local_data_priv_stage0.rs"]
|
|
||||||
mod local_data_priv;
|
|
||||||
#[cfg(not(stage0))]
|
|
||||||
mod local_data_priv;
|
mod local_data_priv;
|
||||||
pub mod rt;
|
pub mod rt;
|
||||||
pub mod spawn;
|
pub mod spawn;
|
||||||
|
|
|
@ -487,14 +487,9 @@ fn kill_taskgroup(state: TaskGroupInner, me: &TaskHandle, is_main: bool) {
|
||||||
|
|
||||||
// FIXME (#2912): Work around core-vs-coretest function duplication. Can't use
|
// FIXME (#2912): Work around core-vs-coretest function duplication. Can't use
|
||||||
// a proper closure because the #[test]s won't understand. Have to fake it.
|
// a proper closure because the #[test]s won't understand. Have to fake it.
|
||||||
#[cfg(not(stage0))]
|
|
||||||
fn taskgroup_key() -> local_data::Key<@@mut Taskgroup> {
|
fn taskgroup_key() -> local_data::Key<@@mut Taskgroup> {
|
||||||
unsafe { cast::transmute(-2) }
|
unsafe { cast::transmute(-2) }
|
||||||
}
|
}
|
||||||
#[cfg(stage0)]
|
|
||||||
fn taskgroup_key() -> local_data::Key<@@mut Taskgroup> {
|
|
||||||
unsafe { cast::transmute((-2, 0)) }
|
|
||||||
}
|
|
||||||
|
|
||||||
// Transitionary.
|
// Transitionary.
|
||||||
struct RuntimeGlue;
|
struct RuntimeGlue;
|
||||||
|
|
|
@ -36,12 +36,8 @@ A quick refresher on memory ordering:
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
pub use realstd::unstable::intrinsics::{TyDesc, Opaque, TyVisitor};
|
pub use realstd::unstable::intrinsics::{TyDesc, Opaque, TyVisitor};
|
||||||
|
|
||||||
#[cfg(not(stage0))]
|
|
||||||
pub type GlueFn = extern "Rust" fn(*i8);
|
pub type GlueFn = extern "Rust" fn(*i8);
|
||||||
|
|
||||||
#[cfg(stage0)]
|
|
||||||
pub type GlueFn = extern "Rust" fn(**TyDesc, *i8);
|
|
||||||
|
|
||||||
// NB: this has to be kept in sync with the Rust ABI.
|
// NB: this has to be kept in sync with the Rust ABI.
|
||||||
#[lang="ty_desc"]
|
#[lang="ty_desc"]
|
||||||
#[cfg(not(test))]
|
#[cfg(not(test))]
|
||||||
|
@ -284,10 +280,7 @@ extern "rust-intrinsic" {
|
||||||
pub fn pref_align_of<T>() -> uint;
|
pub fn pref_align_of<T>() -> uint;
|
||||||
|
|
||||||
/// Get a static pointer to a type descriptor.
|
/// Get a static pointer to a type descriptor.
|
||||||
#[cfg(not(stage0))]
|
|
||||||
pub fn get_tydesc<T>() -> *TyDesc;
|
pub fn get_tydesc<T>() -> *TyDesc;
|
||||||
#[cfg(stage0)]
|
|
||||||
pub fn get_tydesc<T>() -> *();
|
|
||||||
|
|
||||||
/// Create a value initialized to zero.
|
/// Create a value initialized to zero.
|
||||||
///
|
///
|
||||||
|
@ -310,10 +303,8 @@ extern "rust-intrinsic" {
|
||||||
pub fn needs_drop<T>() -> bool;
|
pub fn needs_drop<T>() -> bool;
|
||||||
|
|
||||||
/// Returns `true` if a type is managed (will be allocated on the local heap)
|
/// Returns `true` if a type is managed (will be allocated on the local heap)
|
||||||
#[cfg(not(stage0))]
|
|
||||||
pub fn contains_managed<T>() -> bool;
|
pub fn contains_managed<T>() -> bool;
|
||||||
|
|
||||||
#[cfg(not(stage0))]
|
|
||||||
pub fn visit_tydesc(td: *TyDesc, tv: @TyVisitor);
|
pub fn visit_tydesc(td: *TyDesc, tv: @TyVisitor);
|
||||||
|
|
||||||
pub fn frame_address(f: &once fn(*u8));
|
pub fn frame_address(f: &once fn(*u8));
|
||||||
|
|
|
@ -175,18 +175,16 @@ mod tests {
|
||||||
|
|
||||||
// verify that `#[unsafe_no_drop_flag]` works as intended on a zero-size struct
|
// verify that `#[unsafe_no_drop_flag]` works as intended on a zero-size struct
|
||||||
|
|
||||||
// NOTE: uncomment after snapshot, will not parse yet
|
static mut did_run: bool = false;
|
||||||
//static mut did_run: bool = false;
|
|
||||||
|
|
||||||
struct Foo { five: int }
|
struct Foo { five: int }
|
||||||
|
|
||||||
impl Drop for Foo {
|
impl Drop for Foo {
|
||||||
fn drop(&self) {
|
fn drop(&self) {
|
||||||
assert_eq!(self.five, 5);
|
assert_eq!(self.five, 5);
|
||||||
// NOTE: uncomment after snapshot, will not parse yet
|
unsafe {
|
||||||
//unsafe {
|
did_run = true;
|
||||||
//did_run = true;
|
}
|
||||||
//}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -194,7 +192,6 @@ mod tests {
|
||||||
let _a = (NonCopyable, Foo { five: 5 }, NonCopyable);
|
let _a = (NonCopyable, Foo { five: 5 }, NonCopyable);
|
||||||
}
|
}
|
||||||
|
|
||||||
// NOTE: uncomment after snapshot, will not parse yet
|
unsafe { assert_eq!(did_run, true); }
|
||||||
//unsafe { assert_eq!(did_run, true); }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,16 +25,12 @@ use option::{None, Option, Some};
|
||||||
use ptr::to_unsafe_ptr;
|
use ptr::to_unsafe_ptr;
|
||||||
use ptr;
|
use ptr;
|
||||||
use ptr::RawPtr;
|
use ptr::RawPtr;
|
||||||
#[cfg(not(stage0))]
|
|
||||||
use rt::global_heap::malloc_raw;
|
use rt::global_heap::malloc_raw;
|
||||||
use rt::global_heap::realloc_raw;
|
use rt::global_heap::realloc_raw;
|
||||||
use sys;
|
use sys;
|
||||||
use sys::size_of;
|
use sys::size_of;
|
||||||
use uint;
|
use uint;
|
||||||
use unstable::intrinsics;
|
use unstable::intrinsics;
|
||||||
#[cfg(stage0)]
|
|
||||||
use intrinsic::{get_tydesc};
|
|
||||||
#[cfg(not(stage0))]
|
|
||||||
use unstable::intrinsics::{get_tydesc, contains_managed};
|
use unstable::intrinsics::{get_tydesc, contains_managed};
|
||||||
use vec;
|
use vec;
|
||||||
use util;
|
use util;
|
||||||
|
@ -91,15 +87,6 @@ pub fn from_elem<T:Clone>(n_elts: uint, t: T) -> ~[T] {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a new vector with a capacity of `capacity`
|
/// Creates a new vector with a capacity of `capacity`
|
||||||
#[cfg(stage0)]
|
|
||||||
pub fn with_capacity<T>(capacity: uint) -> ~[T] {
|
|
||||||
let mut vec = ~[];
|
|
||||||
vec.reserve(capacity);
|
|
||||||
vec
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Creates a new vector with a capacity of `capacity`
|
|
||||||
#[cfg(not(stage0))]
|
|
||||||
pub fn with_capacity<T>(capacity: uint) -> ~[T] {
|
pub fn with_capacity<T>(capacity: uint) -> ~[T] {
|
||||||
unsafe {
|
unsafe {
|
||||||
if contains_managed::<T>() {
|
if contains_managed::<T>() {
|
||||||
|
@ -1136,40 +1123,6 @@ impl<T> OwnedVector<T> for ~[T] {
|
||||||
*
|
*
|
||||||
* * n - The number of elements to reserve space for
|
* * n - The number of elements to reserve space for
|
||||||
*/
|
*/
|
||||||
#[cfg(stage0)]
|
|
||||||
fn reserve(&mut self, n: uint) {
|
|
||||||
// Only make the (slow) call into the runtime if we have to
|
|
||||||
use managed;
|
|
||||||
if self.capacity() < n {
|
|
||||||
unsafe {
|
|
||||||
let ptr: *mut *mut raw::VecRepr = cast::transmute(self);
|
|
||||||
let td = get_tydesc::<T>();
|
|
||||||
if ((**ptr).box_header.ref_count ==
|
|
||||||
managed::raw::RC_MANAGED_UNIQUE) {
|
|
||||||
// XXX transmute shouldn't be necessary
|
|
||||||
let td = cast::transmute(td);
|
|
||||||
::at_vec::raw::reserve_raw(td, ptr, n);
|
|
||||||
} else {
|
|
||||||
let alloc = n * sys::nonzero_size_of::<T>();
|
|
||||||
*ptr = realloc_raw(*ptr as *mut c_void, alloc + size_of::<raw::VecRepr>())
|
|
||||||
as *mut raw::VecRepr;
|
|
||||||
(**ptr).unboxed.alloc = alloc;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Reserves capacity for exactly `n` elements in the given vector.
|
|
||||||
*
|
|
||||||
* If the capacity for `self` is already equal to or greater than the requested
|
|
||||||
* capacity, then no action is taken.
|
|
||||||
*
|
|
||||||
* # Arguments
|
|
||||||
*
|
|
||||||
* * n - The number of elements to reserve space for
|
|
||||||
*/
|
|
||||||
#[cfg(not(stage0))]
|
|
||||||
fn reserve(&mut self, n: uint) {
|
fn reserve(&mut self, n: uint) {
|
||||||
// Only make the (slow) call into the runtime if we have to
|
// Only make the (slow) call into the runtime if we have to
|
||||||
if self.capacity() < n {
|
if self.capacity() < n {
|
||||||
|
@ -1213,17 +1166,6 @@ impl<T> OwnedVector<T> for ~[T] {
|
||||||
|
|
||||||
/// Returns the number of elements the vector can hold without reallocating.
|
/// Returns the number of elements the vector can hold without reallocating.
|
||||||
#[inline]
|
#[inline]
|
||||||
#[cfg(stage0)]
|
|
||||||
fn capacity(&self) -> uint {
|
|
||||||
unsafe {
|
|
||||||
let repr: **raw::VecRepr = transmute(self);
|
|
||||||
(**repr).unboxed.alloc / sys::nonzero_size_of::<T>()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns the number of elements the vector can hold without reallocating.
|
|
||||||
#[inline]
|
|
||||||
#[cfg(not(stage0))]
|
|
||||||
fn capacity(&self) -> uint {
|
fn capacity(&self) -> uint {
|
||||||
unsafe {
|
unsafe {
|
||||||
if contains_managed::<T>() {
|
if contains_managed::<T>() {
|
||||||
|
@ -1238,23 +1180,6 @@ impl<T> OwnedVector<T> for ~[T] {
|
||||||
|
|
||||||
/// Append an element to a vector
|
/// Append an element to a vector
|
||||||
#[inline]
|
#[inline]
|
||||||
#[cfg(stage0)]
|
|
||||||
fn push(&mut self, t: T) {
|
|
||||||
unsafe {
|
|
||||||
let repr: **raw::VecRepr = transmute(&mut *self);
|
|
||||||
let fill = (**repr).unboxed.fill;
|
|
||||||
if (**repr).unboxed.alloc <= fill {
|
|
||||||
let new_len = self.len() + 1;
|
|
||||||
self.reserve_at_least(new_len);
|
|
||||||
}
|
|
||||||
|
|
||||||
self.push_fast(t);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Append an element to a vector
|
|
||||||
#[inline]
|
|
||||||
#[cfg(not(stage0))]
|
|
||||||
fn push(&mut self, t: T) {
|
fn push(&mut self, t: T) {
|
||||||
unsafe {
|
unsafe {
|
||||||
if contains_managed::<T>() {
|
if contains_managed::<T>() {
|
||||||
|
@ -1281,19 +1206,6 @@ impl<T> OwnedVector<T> for ~[T] {
|
||||||
|
|
||||||
// This doesn't bother to make sure we have space.
|
// This doesn't bother to make sure we have space.
|
||||||
#[inline] // really pretty please
|
#[inline] // really pretty please
|
||||||
#[cfg(stage0)]
|
|
||||||
unsafe fn push_fast(&mut self, t: 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 p = ptr::offset(p, fill) as *mut T;
|
|
||||||
intrinsics::move_val_init(&mut(*p), t);
|
|
||||||
}
|
|
||||||
|
|
||||||
// This doesn't bother to make sure we have space.
|
|
||||||
#[inline] // really pretty please
|
|
||||||
#[cfg(not(stage0))]
|
|
||||||
unsafe fn push_fast(&mut self, t: T) {
|
unsafe fn push_fast(&mut self, t: T) {
|
||||||
if contains_managed::<T>() {
|
if contains_managed::<T>() {
|
||||||
let repr: **mut raw::VecRepr = transmute(self);
|
let repr: **mut raw::VecRepr = transmute(self);
|
||||||
|
@ -1901,7 +1813,6 @@ pub mod raw {
|
||||||
use sys;
|
use sys;
|
||||||
use unstable::intrinsics;
|
use unstable::intrinsics;
|
||||||
use vec::{UnboxedVecRepr, with_capacity, ImmutableVector, MutableVector};
|
use vec::{UnboxedVecRepr, with_capacity, ImmutableVector, MutableVector};
|
||||||
#[cfg(not(stage0))]
|
|
||||||
use unstable::intrinsics::contains_managed;
|
use unstable::intrinsics::contains_managed;
|
||||||
|
|
||||||
/// The internal representation of a (boxed) vector
|
/// The internal representation of a (boxed) vector
|
||||||
|
@ -1927,21 +1838,6 @@ pub mod raw {
|
||||||
* the vector is actually the specified size.
|
* the vector is actually the specified size.
|
||||||
*/
|
*/
|
||||||
#[inline]
|
#[inline]
|
||||||
#[cfg(stage0)]
|
|
||||||
pub unsafe fn set_len<T>(v: &mut ~[T], new_len: uint) {
|
|
||||||
let repr: **mut VecRepr = transmute(v);
|
|
||||||
(**repr).unboxed.fill = new_len * sys::nonzero_size_of::<T>();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the length of a vector
|
|
||||||
*
|
|
||||||
* This will explicitly set the size of the vector, without actually
|
|
||||||
* modifing its buffers, so it is up to the caller to ensure that
|
|
||||||
* the vector is actually the specified size.
|
|
||||||
*/
|
|
||||||
#[inline]
|
|
||||||
#[cfg(not(stage0))]
|
|
||||||
pub unsafe fn set_len<T>(v: &mut ~[T], new_len: uint) {
|
pub unsafe fn set_len<T>(v: &mut ~[T], new_len: uint) {
|
||||||
if contains_managed::<T>() {
|
if contains_managed::<T>() {
|
||||||
let repr: **mut VecRepr = transmute(v);
|
let repr: **mut VecRepr = transmute(v);
|
||||||
|
@ -2286,19 +2182,6 @@ impl<T> Iterator<T> for VecConsumeRevIterator<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(stage0)]
|
|
||||||
impl<A, T: Iterator<A>> FromIterator<A, T> for ~[A] {
|
|
||||||
pub fn from_iterator(iterator: &mut T) -> ~[A] {
|
|
||||||
let mut xs = ~[];
|
|
||||||
for iterator.advance |x| {
|
|
||||||
xs.push(x);
|
|
||||||
}
|
|
||||||
xs
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#[cfg(not(stage0))]
|
|
||||||
impl<A, T: Iterator<A>> FromIterator<A, T> for ~[A] {
|
impl<A, T: Iterator<A>> FromIterator<A, T> for ~[A] {
|
||||||
pub fn from_iterator(iterator: &mut T) -> ~[A] {
|
pub fn from_iterator(iterator: &mut T) -> ~[A] {
|
||||||
let (lower, _) = iterator.size_hint();
|
let (lower, _) = iterator.size_hint();
|
||||||
|
|
|
@ -704,10 +704,7 @@ pub fn new_sctable_internal() -> SCTable {
|
||||||
|
|
||||||
// fetch the SCTable from TLS, create one if it doesn't yet exist.
|
// fetch the SCTable from TLS, create one if it doesn't yet exist.
|
||||||
pub fn get_sctable() -> @mut SCTable {
|
pub fn get_sctable() -> @mut SCTable {
|
||||||
#[cfg(not(stage0))]
|
|
||||||
static sctable_key: local_data::Key<@@mut SCTable> = &local_data::Key;
|
static sctable_key: local_data::Key<@@mut SCTable> = &local_data::Key;
|
||||||
#[cfg(stage0)]
|
|
||||||
fn sctable_key(_: @@mut SCTable) {}
|
|
||||||
match local_data::get(sctable_key, |k| k.map(|&k| *k)) {
|
match local_data::get(sctable_key, |k| k.map(|&k| *k)) {
|
||||||
None => {
|
None => {
|
||||||
let new_table = @@mut new_sctable_internal();
|
let new_table = @@mut new_sctable_internal();
|
||||||
|
|
|
@ -188,10 +188,7 @@ fn diagnosticcolor(lvl: level) -> term::color::Color {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn print_maybe_styled(msg: &str, color: term::attr::Attr) {
|
fn print_maybe_styled(msg: &str, color: term::attr::Attr) {
|
||||||
#[cfg(not(stage0))]
|
|
||||||
static tls_terminal: local_data::Key<@Option<term::Terminal>> = &local_data::Key;
|
static tls_terminal: local_data::Key<@Option<term::Terminal>> = &local_data::Key;
|
||||||
#[cfg(stage0)]
|
|
||||||
fn tls_terminal(_: @Option<term::Terminal>) {}
|
|
||||||
|
|
||||||
let stderr = io::stderr();
|
let stderr = io::stderr();
|
||||||
|
|
||||||
|
|
|
@ -484,11 +484,8 @@ fn mk_fresh_ident_interner() -> @ident_interner {
|
||||||
// if an interner exists in TLS, return it. Otherwise, prepare a
|
// if an interner exists in TLS, return it. Otherwise, prepare a
|
||||||
// fresh one.
|
// fresh one.
|
||||||
pub fn get_ident_interner() -> @ident_interner {
|
pub fn get_ident_interner() -> @ident_interner {
|
||||||
#[cfg(not(stage0))]
|
|
||||||
static key: local_data::Key<@@::parse::token::ident_interner> =
|
static key: local_data::Key<@@::parse::token::ident_interner> =
|
||||||
&local_data::Key;
|
&local_data::Key;
|
||||||
#[cfg(stage0)]
|
|
||||||
fn key(_: @@::parse::token::ident_interner) {}
|
|
||||||
match local_data::get(key, |k| k.map(|&k| *k)) {
|
match local_data::get(key, |k| k.map(|&k| *k)) {
|
||||||
Some(interner) => *interner,
|
Some(interner) => *interner,
|
||||||
None => {
|
None => {
|
||||||
|
|
|
@ -183,9 +183,6 @@ void task_start_wrapper(spawn_args *a)
|
||||||
// free the environment (which should be a unique closure).
|
// free the environment (which should be a unique closure).
|
||||||
const type_desc *td = env->td;
|
const type_desc *td = env->td;
|
||||||
td->drop_glue(NULL,
|
td->drop_glue(NULL,
|
||||||
#ifdef _RUST_STAGE0
|
|
||||||
NULL,
|
|
||||||
#endif
|
|
||||||
box_body(env));
|
box_body(env));
|
||||||
task->kernel->region()->free(env);
|
task->kernel->region()->free(env);
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,9 +26,6 @@ typedef void (*CDECL spawn_fn)(rust_opaque_box*, void *);
|
||||||
struct type_desc;
|
struct type_desc;
|
||||||
|
|
||||||
typedef void CDECL (glue_fn)(void *,
|
typedef void CDECL (glue_fn)(void *,
|
||||||
#ifdef _RUST_STAGE0
|
|
||||||
const type_desc **,
|
|
||||||
#endif
|
|
||||||
void *);
|
void *);
|
||||||
|
|
||||||
// Corresponds to the boxed data in the @ region. The body follows the
|
// Corresponds to the boxed data in the @ region. The body follows the
|
||||||
|
|
|
@ -1,3 +1,11 @@
|
||||||
|
S 2013-07-21 e336cbf
|
||||||
|
macos-i386 d9666dccc1040ebe298a54acb378902a7472ad0f
|
||||||
|
macos-x86_64 808f68916444e3857ef2aab20f8db9db8f4b0b4a
|
||||||
|
winnt-i386 f9a5f891fd24e9446acb2a1b5d697461665c4388
|
||||||
|
freebsd-x86_64 8e79f6e970bc33ea6a3b9329bc4526d89ca63d47
|
||||||
|
linux-i386 054a0229b9cbdadf013868ba01a8277883f83a6d
|
||||||
|
linux-x86_64 2c53a72e9c9bb547df248a2d4b857d480ce0b910
|
||||||
|
|
||||||
S 2013-06-23 f827561
|
S 2013-06-23 f827561
|
||||||
macos-i386 63ffbcf99b6853d7840bdfe01380068518d0e466
|
macos-i386 63ffbcf99b6853d7840bdfe01380068518d0e466
|
||||||
macos-x86_64 b34fdf3845f8ef4760817007d8ef820cd32f2e07
|
macos-x86_64 b34fdf3845f8ef4760817007d8ef820cd32f2e07
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue