Merge remote-tracking branch 'mozilla/master'

Conflicts:
	src/libextra/test.rs
	src/libstd/at_vec.rs
	src/libstd/cleanup.rs
	src/libstd/rt/comm.rs
	src/libstd/rt/global_heap.rs
	src/libstd/task/spawn.rs
	src/libstd/unstable/lang.rs
	src/libstd/vec.rs
	src/rt/rustrt.def.in
	src/test/run-pass/extern-pub.rs
This commit is contained in:
Brian Anderson 2013-07-02 17:36:58 -07:00
commit 1098d6980b
765 changed files with 23500 additions and 17316 deletions

View file

@ -62,6 +62,7 @@ pub struct AtomicPtr<T> {
/**
* An owned atomic pointer. Ensures that only a single reference to the data is held at any time.
*/
#[unsafe_no_drop_flag]
pub struct AtomicOption<T> {
priv p: *mut c_void
}
@ -275,7 +276,7 @@ impl<T> AtomicOption<T> {
#[unsafe_destructor]
impl<T> Drop for AtomicOption<T> {
fn finalize(&self) {
fn drop(&self) {
// This will ensure that the contained data is
// destroyed, unless it's null.
unsafe {

View file

@ -25,7 +25,7 @@ use result::*;
pub struct DynamicLibrary { priv handle: *libc::c_void }
impl Drop for DynamicLibrary {
fn finalize(&self) {
fn drop(&self) {
match do dl::check_for_errors_in {
unsafe {
dl::close(self.handle)
@ -164,7 +164,6 @@ mod dl {
use libc;
use path;
use ptr;
use str;
use task;
use result::*;
@ -175,7 +174,7 @@ mod dl {
}
pub unsafe fn open_internal() -> *libc::c_void {
let mut handle = ptr::null();
let handle = ptr::null();
GetModuleHandleExW(0 as libc::DWORD, ptr::null(), &handle as **libc::c_void);
handle
}

View file

@ -1,83 +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.
use sys::{TypeDesc, size_of};
use libc::{c_void, size_t};
use c_malloc = libc::malloc;
use c_free = libc::free;
use managed::raw::{BoxHeaderRepr, BoxRepr};
use cast::transmute;
use unstable::intrinsics::{atomic_xadd,atomic_xsub};
use ptr::null;
use intrinsic::TyDesc;
pub unsafe fn malloc(td: *TypeDesc, size: uint) -> *c_void {
assert!(td.is_not_null());
let total_size = get_box_size(size, (*td).align);
let p = c_malloc(total_size as size_t);
assert!(p.is_not_null());
// FIXME #3475: Converting between our two different tydesc types
let td: *TyDesc = transmute(td);
let box: &mut BoxRepr = transmute(p);
box.header.ref_count = -1; // Exchange values not ref counted
box.header.type_desc = td;
box.header.prev = null();
box.header.next = null();
let exchange_count = &mut *rust_get_exchange_count_ptr();
atomic_xadd(exchange_count, 1);
return transmute(box);
}
/**
Thin wrapper around libc::malloc, none of the box header
stuff in exchange_alloc::malloc
*/
pub unsafe fn malloc_raw(size: uint) -> *c_void {
let p = c_malloc(size as size_t);
if p.is_null() {
fail!("Failure in malloc_raw: result ptr is null");
}
p
}
pub unsafe fn free(ptr: *c_void) {
let exchange_count = &mut *rust_get_exchange_count_ptr();
atomic_xsub(exchange_count, 1);
assert!(ptr.is_not_null());
c_free(ptr);
}
///Thin wrapper around libc::free, as with exchange_alloc::malloc_raw
pub unsafe fn free_raw(ptr: *c_void) {
c_free(ptr);
}
fn get_box_size(body_size: uint, body_align: uint) -> uint {
let header_size = size_of::<BoxHeaderRepr>();
// FIXME (#2699): This alignment calculation is suspicious. Is it right?
let total_size = align_to(header_size, body_align) + body_size;
return total_size;
}
// Rounds |size| to the nearest |alignment|. Invariant: |alignment| is a power
// of two.
fn align_to(size: uint, align: uint) -> uint {
assert!(align != 0);
(size + align - 1) & !(align - 1)
}
extern {
#[rust_stack]
fn rust_get_exchange_count_ptr() -> *mut int;
}

View file

@ -94,6 +94,7 @@ use iterator::IteratorUtil;
#[doc(hidden)]
pub mod ct {
use char;
use container::Container;
use prelude::*;
use str;
@ -350,7 +351,7 @@ pub mod ct {
#[test]
fn test_parse_flags() {
fn pack(fs: &[Flag]) -> uint {
fs.foldl(0, |&p, &f| p | (1 << f as uint))
fs.iter().fold(0, |p, &f| p | (1 << f as uint))
}
fn test(s: &str, flags: &[Flag], next: uint) {

View file

@ -64,7 +64,7 @@ struct Finallyalizer<'self> {
#[unsafe_destructor]
impl<'self> Drop for Finallyalizer<'self> {
fn finalize(&self) {
fn drop(&self) {
(self.dtor)();
}
}

View file

@ -27,7 +27,7 @@ avoid hitting the mutex.
use cast::{transmute};
use clone::Clone;
use kinds::Owned;
use kinds::Send;
use libc::{c_void};
use option::{Option, Some, None};
use ops::Drop;
@ -43,7 +43,7 @@ use sys::Closure;
pub type GlobalDataKey<'self,T> = &'self fn(v: T);
pub unsafe fn global_data_clone_create<T:Owned + Clone>(
pub unsafe fn global_data_clone_create<T:Send + Clone>(
key: GlobalDataKey<T>, create: &fn() -> ~T) -> T {
/*!
* Clone a global value or, if it has not been created,
@ -59,7 +59,7 @@ pub unsafe fn global_data_clone_create<T:Owned + Clone>(
global_data_clone_create_(key_ptr(key), create)
}
unsafe fn global_data_clone_create_<T:Owned + Clone>(
unsafe fn global_data_clone_create_<T:Send + Clone>(
key: uint, create: &fn() -> ~T) -> T {
let mut clone_value: Option<T> = None;
@ -79,13 +79,13 @@ unsafe fn global_data_clone_create_<T:Owned + Clone>(
return clone_value.unwrap();
}
unsafe fn global_data_modify<T:Owned>(
unsafe fn global_data_modify<T:Send>(
key: GlobalDataKey<T>, op: &fn(Option<~T>) -> Option<~T>) {
global_data_modify_(key_ptr(key), op)
}
unsafe fn global_data_modify_<T:Owned>(
unsafe fn global_data_modify_<T:Send>(
key: uint, op: &fn(Option<~T>) -> Option<~T>) {
let mut old_dtor = None;
@ -124,7 +124,7 @@ unsafe fn global_data_modify_<T:Owned>(
}
}
pub unsafe fn global_data_clone<T:Owned + Clone>(
pub unsafe fn global_data_clone<T:Send + Clone>(
key: GlobalDataKey<T>) -> Option<T> {
let mut maybe_clone: Option<T> = None;
do global_data_modify(key) |current| {
@ -147,7 +147,7 @@ struct GlobalState {
}
impl Drop for GlobalState {
fn finalize(&self) {
fn drop(&self) {
for self.map.each_value |v| {
match v {
&(_, ref dtor) => (*dtor)()
@ -220,7 +220,7 @@ fn get_global_state() -> Exclusive<GlobalState> {
}
}
fn key_ptr<T:Owned>(key: GlobalDataKey<T>) -> uint {
fn key_ptr<T:Send>(key: GlobalDataKey<T>) -> uint {
unsafe {
let closure: Closure = transmute(key);
return transmute(closure.code);

View file

@ -32,6 +32,130 @@ A quick refresher on memory ordering:
*/
// This is needed to prevent duplicate lang item definitions.
#[cfg(test)]
pub use realstd::unstable::intrinsics::{TyDesc, Opaque, TyVisitor};
#[cfg(not(stage0))]
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.
#[lang="ty_desc"]
#[cfg(not(test))]
pub struct TyDesc {
size: uint,
align: uint,
take_glue: GlueFn,
drop_glue: GlueFn,
free_glue: GlueFn,
visit_glue: GlueFn,
}
#[lang="opaque"]
#[cfg(not(test))]
pub enum Opaque { }
#[lang="ty_visitor"]
#[cfg(not(test))]
pub trait TyVisitor {
fn visit_bot(&self) -> bool;
fn visit_nil(&self) -> bool;
fn visit_bool(&self) -> bool;
fn visit_int(&self) -> bool;
fn visit_i8(&self) -> bool;
fn visit_i16(&self) -> bool;
fn visit_i32(&self) -> bool;
fn visit_i64(&self) -> bool;
fn visit_uint(&self) -> bool;
fn visit_u8(&self) -> bool;
fn visit_u16(&self) -> bool;
fn visit_u32(&self) -> bool;
fn visit_u64(&self) -> bool;
fn visit_float(&self) -> bool;
fn visit_f32(&self) -> bool;
fn visit_f64(&self) -> bool;
fn visit_char(&self) -> bool;
fn visit_str(&self) -> bool;
fn visit_estr_box(&self) -> bool;
fn visit_estr_uniq(&self) -> bool;
fn visit_estr_slice(&self) -> bool;
fn visit_estr_fixed(&self, n: uint, sz: uint, align: uint) -> bool;
fn visit_box(&self, mtbl: uint, inner: *TyDesc) -> bool;
fn visit_uniq(&self, mtbl: uint, inner: *TyDesc) -> bool;
fn visit_ptr(&self, mtbl: uint, inner: *TyDesc) -> bool;
fn visit_rptr(&self, mtbl: uint, inner: *TyDesc) -> bool;
fn visit_vec(&self, mtbl: uint, inner: *TyDesc) -> bool;
fn visit_unboxed_vec(&self, mtbl: uint, inner: *TyDesc) -> bool;
fn visit_evec_box(&self, mtbl: uint, inner: *TyDesc) -> bool;
fn visit_evec_uniq(&self, mtbl: uint, inner: *TyDesc) -> bool;
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;
fn visit_enter_rec(&self, n_fields: uint,
sz: uint, align: uint) -> bool;
fn visit_rec_field(&self, i: uint, name: &str,
mtbl: uint, inner: *TyDesc) -> bool;
fn visit_leave_rec(&self, n_fields: uint,
sz: uint, align: uint) -> bool;
fn visit_enter_class(&self, n_fields: uint,
sz: uint, align: uint) -> bool;
fn visit_class_field(&self, i: uint, name: &str,
mtbl: uint, inner: *TyDesc) -> bool;
fn visit_leave_class(&self, n_fields: uint,
sz: uint, align: uint) -> bool;
fn visit_enter_tup(&self, n_fields: uint,
sz: uint, align: uint) -> bool;
fn visit_tup_field(&self, i: uint, inner: *TyDesc) -> bool;
fn visit_leave_tup(&self, n_fields: uint,
sz: uint, align: uint) -> bool;
fn visit_enter_enum(&self, n_variants: uint,
get_disr: extern unsafe fn(ptr: *Opaque) -> int,
sz: uint, align: uint) -> bool;
fn visit_enter_enum_variant(&self, variant: uint,
disr_val: int,
n_fields: uint,
name: &str) -> bool;
fn visit_enum_variant_field(&self, i: uint, offset: uint, inner: *TyDesc) -> bool;
fn visit_leave_enum_variant(&self, variant: uint,
disr_val: int,
n_fields: uint,
name: &str) -> bool;
fn visit_leave_enum(&self, n_variants: uint,
get_disr: extern unsafe fn(ptr: *Opaque) -> int,
sz: uint, align: uint) -> bool;
fn visit_enter_fn(&self, purity: uint, proto: uint,
n_inputs: uint, retstyle: uint) -> bool;
fn visit_fn_input(&self, i: uint, mode: uint, inner: *TyDesc) -> bool;
fn visit_fn_output(&self, retstyle: uint, inner: *TyDesc) -> bool;
fn visit_leave_fn(&self, purity: uint, proto: uint,
n_inputs: uint, retstyle: uint) -> bool;
fn visit_trait(&self) -> bool;
fn visit_var(&self) -> bool;
fn visit_var_integral(&self) -> bool;
fn visit_param(&self, i: uint) -> bool;
fn visit_self(&self) -> bool;
fn visit_type(&self) -> bool;
fn visit_opaque_box(&self) -> bool;
fn visit_constr(&self, inner: *TyDesc) -> bool;
fn visit_closure_ptr(&self, ck: uint) -> bool;
}
#[abi = "rust-intrinsic"]
pub extern "rust-intrinsic" {
@ -42,22 +166,32 @@ pub extern "rust-intrinsic" {
/// Atomic compare and exchange, release ordering.
pub fn atomic_cxchg_rel(dst: &mut int, old: int, src: int) -> int;
pub fn atomic_cxchg_acqrel(dst: &mut int, old: int, src: int) -> int;
pub fn atomic_cxchg_relaxed(dst: &mut int, old: int, src: int) -> int;
/// Atomic load, sequentially consistent.
pub fn atomic_load(src: &int) -> int;
/// Atomic load, acquire ordering.
pub fn atomic_load_acq(src: &int) -> int;
pub fn atomic_load_relaxed(src: &int) -> int;
/// Atomic store, sequentially consistent.
pub fn atomic_store(dst: &mut int, val: int);
/// Atomic store, release ordering.
pub fn atomic_store_rel(dst: &mut int, val: int);
pub fn atomic_store_relaxed(dst: &mut int, val: int);
/// Atomic exchange, sequentially consistent.
pub fn atomic_xchg(dst: &mut int, src: int) -> int;
/// Atomic exchange, acquire ordering.
pub fn atomic_xchg_acq(dst: &mut int, src: int) -> int;
/// Atomic exchange, release ordering.
pub fn atomic_xchg_rel(dst: &mut int, src: int) -> int;
pub fn atomic_xchg_acqrel(dst: &mut int, src: int) -> int;
pub fn atomic_xchg_relaxed(dst: &mut int, src: int) -> int;
/// Atomic addition, sequentially consistent.
pub fn atomic_xadd(dst: &mut int, src: int) -> int;
@ -65,6 +199,8 @@ pub extern "rust-intrinsic" {
pub fn atomic_xadd_acq(dst: &mut int, src: int) -> int;
/// Atomic addition, release ordering.
pub fn atomic_xadd_rel(dst: &mut int, src: int) -> int;
pub fn atomic_xadd_acqrel(dst: &mut int, src: int) -> int;
pub fn atomic_xadd_relaxed(dst: &mut int, src: int) -> int;
/// Atomic subtraction, sequentially consistent.
pub fn atomic_xsub(dst: &mut int, src: int) -> int;
@ -72,6 +208,56 @@ pub extern "rust-intrinsic" {
pub fn atomic_xsub_acq(dst: &mut int, src: int) -> int;
/// Atomic subtraction, release ordering.
pub fn atomic_xsub_rel(dst: &mut int, src: int) -> int;
pub fn atomic_xsub_acqrel(dst: &mut int, src: int) -> int;
pub fn atomic_xsub_relaxed(dst: &mut int, src: int) -> int;
pub fn atomic_and(dst: &mut int, src: int) -> int;
pub fn atomic_and_acq(dst: &mut int, src: int) -> int;
pub fn atomic_and_rel(dst: &mut int, src: int) -> int;
pub fn atomic_and_acqrel(dst: &mut int, src: int) -> int;
pub fn atomic_and_relaxed(dst: &mut int, src: int) -> int;
pub fn atomic_nand(dst: &mut int, src: int) -> int;
pub fn atomic_nand_acq(dst: &mut int, src: int) -> int;
pub fn atomic_nand_rel(dst: &mut int, src: int) -> int;
pub fn atomic_nand_acqrel(dst: &mut int, src: int) -> int;
pub fn atomic_nand_relaxed(dst: &mut int, src: int) -> int;
pub fn atomic_or(dst: &mut int, src: int) -> int;
pub fn atomic_or_acq(dst: &mut int, src: int) -> int;
pub fn atomic_or_rel(dst: &mut int, src: int) -> int;
pub fn atomic_or_acqrel(dst: &mut int, src: int) -> int;
pub fn atomic_or_relaxed(dst: &mut int, src: int) -> int;
pub fn atomic_xor(dst: &mut int, src: int) -> int;
pub fn atomic_xor_acq(dst: &mut int, src: int) -> int;
pub fn atomic_xor_rel(dst: &mut int, src: int) -> int;
pub fn atomic_xor_acqrel(dst: &mut int, src: int) -> int;
pub fn atomic_xor_relaxed(dst: &mut int, src: int) -> int;
pub fn atomic_max(dst: &mut int, src: int) -> int;
pub fn atomic_max_acq(dst: &mut int, src: int) -> int;
pub fn atomic_max_rel(dst: &mut int, src: int) -> int;
pub fn atomic_max_acqrel(dst: &mut int, src: int) -> int;
pub fn atomic_max_relaxed(dst: &mut int, src: int) -> int;
pub fn atomic_min(dst: &mut int, src: int) -> int;
pub fn atomic_min_acq(dst: &mut int, src: int) -> int;
pub fn atomic_min_rel(dst: &mut int, src: int) -> int;
pub fn atomic_min_acqrel(dst: &mut int, src: int) -> int;
pub fn atomic_min_relaxed(dst: &mut int, src: int) -> int;
pub fn atomic_umin(dst: &mut int, src: int) -> int;
pub fn atomic_umin_acq(dst: &mut int, src: int) -> int;
pub fn atomic_umin_rel(dst: &mut int, src: int) -> int;
pub fn atomic_umin_acqrel(dst: &mut int, src: int) -> int;
pub fn atomic_umin_relaxed(dst: &mut int, src: int) -> int;
pub fn atomic_umax(dst: &mut int, src: int) -> int;
pub fn atomic_umax_acq(dst: &mut int, src: int) -> int;
pub fn atomic_umax_rel(dst: &mut int, src: int) -> int;
pub fn atomic_umax_acqrel(dst: &mut int, src: int) -> int;
pub fn atomic_umax_relaxed(dst: &mut int, src: int) -> int;
/// The size of a type in bytes.
///
@ -97,6 +283,9 @@ pub extern "rust-intrinsic" {
pub fn pref_align_of<T>() -> uint;
/// Get a static pointer to a type descriptor.
#[cfg(not(stage0))]
pub fn get_tydesc<T>() -> *TyDesc;
#[cfg(stage0)]
pub fn get_tydesc<T>() -> *();
/// Create a value initialized to zero.
@ -119,9 +308,12 @@ pub extern "rust-intrinsic" {
/// Returns `true` if a type requires drop glue.
pub fn needs_drop<T>() -> bool;
// XXX: intrinsic uses legacy modes and has reference to TyDesc
// and TyVisitor which are in librustc
//fn visit_tydesc(++td: *TyDesc, &&tv: TyVisitor) -> ();
/// Returns `true` if a type is managed (will be allocated on the local heap)
#[cfg(not(stage0))]
pub fn contains_managed<T>() -> bool;
#[cfg(not(stage0))]
pub fn visit_tydesc(td: *TyDesc, tv: @TyVisitor);
pub fn frame_address(f: &once fn(*u8));

View file

@ -10,27 +10,21 @@
//! Runtime calls emitted by the compiler.
use iterator::IteratorUtil;
use uint;
use cast::transmute;
use libc::{c_char, c_uchar, c_void, size_t, uintptr_t, c_int, STDERR_FILENO};
use libc::{c_char, c_uchar, c_void, size_t, uintptr_t, c_int};
use str;
use sys;
use rt::{context, OldTaskContext};
use rt::task::Task;
use rt::local::Local;
use option::{Option, Some, None};
use io;
use rt::global_heap;
use rt::borrowck;
use borrow::to_uint;
#[allow(non_camel_case_types)]
pub type rust_task = c_void;
pub mod rustrt {
use unstable::lang::rust_task;
use libc::{c_void, c_char, uintptr_t};
use libc::{c_char, uintptr_t};
pub extern {
#[rust_stack]
@ -66,22 +60,6 @@ pub fn fail_bounds_check(file: *c_char, line: size_t,
}
}
// FIXME #4942: Make these signatures agree with exchange_alloc's signatures
#[lang="exchange_malloc"]
#[inline]
pub unsafe fn exchange_malloc(td: *c_char, size: uintptr_t) -> *c_char {
transmute(global_heap::malloc(transmute(td), transmute(size)))
}
// NB: Calls to free CANNOT be allowed to fail, as throwing an exception from
// inside a landing pad may corrupt the state of the exception handler. If a
// problem occurs, call exit instead.
#[lang="exchange_free"]
#[inline]
pub unsafe fn exchange_free(ptr: *c_char) {
global_heap::free(transmute(ptr))
}
#[lang="malloc"]
pub unsafe fn local_malloc(td: *c_char, size: uintptr_t) -> *c_char {
match context() {

View file

@ -17,7 +17,7 @@ use unstable::finally::Finally;
use unstable::intrinsics;
use ops::Drop;
use clone::Clone;
use kinds::Owned;
use kinds::Send;
/// An atomically reference counted pointer.
///
@ -31,7 +31,7 @@ struct AtomicRcBoxData<T> {
data: Option<T>,
}
impl<T: Owned> UnsafeAtomicRcBox<T> {
impl<T: Send> UnsafeAtomicRcBox<T> {
pub fn new(data: T) -> UnsafeAtomicRcBox<T> {
unsafe {
let data = ~AtomicRcBoxData { count: 1, data: Some(data) };
@ -61,7 +61,7 @@ impl<T: Owned> UnsafeAtomicRcBox<T> {
}
}
impl<T: Owned> Clone for UnsafeAtomicRcBox<T> {
impl<T: Send> Clone for UnsafeAtomicRcBox<T> {
fn clone(&self) -> UnsafeAtomicRcBox<T> {
unsafe {
let mut data: ~AtomicRcBoxData<T> = cast::transmute(self.data);
@ -75,7 +75,7 @@ impl<T: Owned> Clone for UnsafeAtomicRcBox<T> {
#[unsafe_destructor]
impl<T> Drop for UnsafeAtomicRcBox<T>{
fn finalize(&self) {
fn drop(&self) {
unsafe {
do task::unkillable {
let mut data: ~AtomicRcBoxData<T> = cast::transmute(self.data);
@ -102,7 +102,7 @@ struct LittleLock {
}
impl Drop for LittleLock {
fn finalize(&self) {
fn drop(&self) {
unsafe {
rust_destroy_little_lock(self.l);
}
@ -144,7 +144,7 @@ pub struct Exclusive<T> {
x: UnsafeAtomicRcBox<ExData<T>>
}
pub fn exclusive<T:Owned>(user_data: T) -> Exclusive<T> {
pub fn exclusive<T:Send>(user_data: T) -> Exclusive<T> {
let data = ExData {
lock: LittleLock(),
failed: false,
@ -155,14 +155,14 @@ pub fn exclusive<T:Owned>(user_data: T) -> Exclusive<T> {
}
}
impl<T:Owned> Clone for Exclusive<T> {
impl<T:Send> Clone for Exclusive<T> {
// Duplicate an exclusive ARC, as std::arc::clone.
fn clone(&self) -> Exclusive<T> {
Exclusive { x: self.x.clone() }
}
}
impl<T:Owned> Exclusive<T> {
impl<T:Send> Exclusive<T> {
// Exactly like std::arc::mutex_arc,access(), but with the little_lock
// instead of a proper mutex. Same reason for being unsafe.
//
@ -282,7 +282,7 @@ mod tests {
}
};
for futures.each |f| { f.recv() }
for futures.iter().advance |f| { f.recv() }
do total.with |total| {
assert!(**total == num_tasks * count)