diff options
| author | bors <bors@rust-lang.org> | 2013-06-25 04:38:06 -0700 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2013-06-25 04:38:06 -0700 |
| commit | 7aee5da08db11dc597907bf228c2e716a408fdab (patch) | |
| tree | 7217207f8ec916aca96034f94d64a15746e22f79 /src/libstd | |
| parent | b11346bb5d2659313eb96f3108137f01239785c9 (diff) | |
| parent | f8ae3cdcaacb29c7b56e546a9ddab1396b615f8f (diff) | |
| download | rust-7aee5da08db11dc597907bf228c2e716a408fdab.tar.gz rust-7aee5da08db11dc597907bf228c2e716a408fdab.zip | |
auto merge of #7254 : Blei/rust/intrinsic-overhaul, r=cmr
This sets the `get_tydesc()` return type correctly and removes the intrinsic module. See #3730, #3475. Update: this now also removes the unused shape fields in tydescs.
Diffstat (limited to 'src/libstd')
| -rw-r--r-- | src/libstd/at_vec.rs | 13 | ||||
| -rw-r--r-- | src/libstd/cleanup.rs | 30 | ||||
| -rw-r--r-- | src/libstd/gc.rs | 28 | ||||
| -rw-r--r-- | src/libstd/managed.rs | 2 | ||||
| -rw-r--r-- | src/libstd/reflect.rs | 6 | ||||
| -rw-r--r-- | src/libstd/repr.rs | 20 | ||||
| -rw-r--r-- | src/libstd/rt/global_heap.rs | 10 | ||||
| -rw-r--r-- | src/libstd/sys.rs | 31 | ||||
| -rw-r--r-- | src/libstd/unstable/exchange_alloc.rs | 10 | ||||
| -rw-r--r-- | src/libstd/unstable/intrinsics.rs | 132 | ||||
| -rw-r--r-- | src/libstd/vec.rs | 15 |
11 files changed, 217 insertions, 80 deletions
diff --git a/src/libstd/at_vec.rs b/src/libstd/at_vec.rs index b871ed3d57a..5a2f948600a 100644 --- a/src/libstd/at_vec.rs +++ b/src/libstd/at_vec.rs @@ -25,13 +25,16 @@ use vec::ImmutableVector; pub mod rustrt { use libc; - use sys; use vec; + #[cfg(stage0)] + use intrinsic::{TyDesc}; + #[cfg(not(stage0))] + use unstable::intrinsics::{TyDesc}; #[abi = "cdecl"] #[link_name = "rustrt"] pub extern { - pub unsafe fn vec_reserve_shared_actual(t: *sys::TypeDesc, + pub unsafe fn vec_reserve_shared_actual(t: *TyDesc, v: **vec::raw::VecRepr, n: libc::size_t); } @@ -197,6 +200,10 @@ pub mod raw { use uint; use unstable::intrinsics::{move_val_init}; use vec; + #[cfg(stage0)] + use intrinsic::{get_tydesc}; + #[cfg(not(stage0))] + use unstable::intrinsics::{get_tydesc}; pub type VecRepr = vec::raw::VecRepr; pub type SliceRepr = vec::raw::SliceRepr; @@ -258,7 +265,7 @@ pub mod raw { // Only make the (slow) call into the runtime if we have to if capacity(*v) < n { let ptr: **VecRepr = transmute(v); - rustrt::vec_reserve_shared_actual(sys::get_type_desc::<T>(), + rustrt::vec_reserve_shared_actual(get_tydesc::<T>(), ptr, n as libc::size_t); } } diff --git a/src/libstd/cleanup.rs b/src/libstd/cleanup.rs index d1460b7a3c9..ee9fdd3c620 100644 --- a/src/libstd/cleanup.rs +++ b/src/libstd/cleanup.rs @@ -10,24 +10,19 @@ #[doc(hidden)]; -use libc::{c_char, c_void, intptr_t, uintptr_t}; -use ptr::mut_null; +use libc::{c_char, intptr_t, uintptr_t}; +use ptr::{mut_null}; use repr::BoxRepr; -use sys::TypeDesc; use cast::transmute; +use unstable::intrinsics::TyDesc; #[cfg(not(test))] use unstable::lang::clear_task_borrow_list; -#[cfg(not(test))] use ptr::to_unsafe_ptr; - /** * Runtime structures * * NB: These must match the representation in the C++ runtime. */ -type DropGlue<'self> = &'self fn(**TypeDesc, *c_void); -type FreeGlue<'self> = &'self fn(**TypeDesc, *c_void); - type TaskID = uintptr_t; struct StackSegment { priv opaque: () } @@ -164,6 +159,19 @@ fn debug_mem() -> 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); +} + /// Destroys all managed memory (i.e. @ boxes) held by the current task. #[cfg(not(test))] #[lang="annihilate"] @@ -205,9 +213,9 @@ pub unsafe fn annihilate() { // callback, as the original value may have been freed. for each_live_alloc(false) |box, uniq| { if !uniq { - let tydesc: *TypeDesc = transmute(copy (*box).header.type_desc); - let drop_glue: DropGlue = transmute(((*tydesc).drop_glue, 0)); - drop_glue(to_unsafe_ptr(&tydesc), transmute(&(*box).data)); + let tydesc = (*box).header.type_desc; + let data = transmute(&(*box).data); + call_drop_glue(tydesc, data); } } diff --git a/src/libstd/gc.rs b/src/libstd/gc.rs index 611b95a7745..c9e33219fa5 100644 --- a/src/libstd/gc.rs +++ b/src/libstd/gc.rs @@ -40,12 +40,13 @@ with destructors. use cast; use container::{Map, Set}; use io; -use libc::{size_t, uintptr_t}; +use libc::{uintptr_t}; use option::{None, Option, Some}; use ptr; use hashmap::HashSet; use stackwalk::walk_stack; use sys; +use unstable::intrinsics::{TyDesc}; pub use stackwalk::Word; @@ -58,18 +59,12 @@ pub struct StackSegment { } pub mod rustrt { - use libc::size_t; use stackwalk::Word; use super::StackSegment; #[link_name = "rustrt"] pub extern { #[rust_stack] - pub unsafe fn rust_call_tydesc_glue(root: *Word, - tydesc: *Word, - field: size_t); - - #[rust_stack] pub unsafe fn rust_gc_metadata() -> *Word; pub unsafe fn rust_get_stack_segment() -> *StackSegment; @@ -125,7 +120,7 @@ unsafe fn is_safe_point(pc: *Word) -> Option<SafePoint> { return None; } -type Visitor<'self> = &'self fn(root: **Word, tydesc: *Word) -> bool; +type Visitor<'self> = &'self fn(root: **Word, tydesc: *TyDesc) -> bool; // Walks the list of roots for the given safe point, and calls visitor // on each root. @@ -139,7 +134,7 @@ unsafe fn _walk_safe_point(fp: *Word, sp: SafePoint, visitor: Visitor) -> bool { let stack_roots: *u32 = bump(sp_meta, 2); let reg_roots: *u8 = bump(stack_roots, num_stack_roots); let addrspaces: *Word = align_to_pointer(bump(reg_roots, num_reg_roots)); - let tydescs: ***Word = bump(addrspaces, num_stack_roots); + let tydescs: ***TyDesc = bump(addrspaces, num_stack_roots); // Stack roots let mut sri = 0; @@ -321,6 +316,19 @@ fn expect_sentinel() -> bool { true } #[cfg(nogc)] 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 // heap and stack allocations requiring drop, and runs all // destructors. @@ -364,7 +372,7 @@ pub fn cleanup_stack_for_failure() { // FIXME #4420: Destroy this box // FIXME #4330: Destroy this box } else { - rustrt::rust_call_tydesc_glue(*root, tydesc, 3 as size_t); + call_drop_glue(tydesc, *root as *i8); } } } diff --git a/src/libstd/managed.rs b/src/libstd/managed.rs index d514612b5af..b71b3b503c2 100644 --- a/src/libstd/managed.rs +++ b/src/libstd/managed.rs @@ -15,7 +15,7 @@ use ptr::to_unsafe_ptr; #[cfg(not(test))] use cmp::{Eq, Ord}; pub mod raw { - use intrinsic::TyDesc; + use std::unstable::intrinsics::TyDesc; pub static RC_EXCHANGE_UNIQUE : uint = (-1) as uint; pub static RC_MANAGED_UNIQUE : uint = (-2) as uint; diff --git a/src/libstd/reflect.rs b/src/libstd/reflect.rs index d276abf0c8b..16ab4771d0d 100644 --- a/src/libstd/reflect.rs +++ b/src/libstd/reflect.rs @@ -16,8 +16,10 @@ Runtime type reflection #[allow(missing_doc)]; -use intrinsic::{TyDesc, TyVisitor}; -use intrinsic::Opaque; +#[cfg(stage0)] +use intrinsic::{Opaque, TyDesc, TyVisitor}; +#[cfg(not(stage0))] +use unstable::intrinsics::{Opaque, TyDesc, TyVisitor}; use libc::c_void; use sys; use vec; diff --git a/src/libstd/repr.rs b/src/libstd/repr.rs index ab3f83d34d5..f39b5a00ed0 100644 --- a/src/libstd/repr.rs +++ b/src/libstd/repr.rs @@ -19,9 +19,6 @@ More runtime type reflection use cast::transmute; use char; use container::Container; -use intrinsic; -use intrinsic::{TyDesc, TyVisitor, visit_tydesc}; -use intrinsic::Opaque; use io::{Writer, WriterUtil}; use iterator::IteratorUtil; use libc::c_void; @@ -34,6 +31,10 @@ use to_str::ToStr; use vec::raw::{VecRepr, SliceRepr}; use vec; 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}; #[cfg(test)] use io; @@ -564,6 +565,7 @@ impl TyVisitor for ReprVisitor { fn visit_self(&self) -> bool { true } fn visit_type(&self) -> bool { true } + #[cfg(not(stage0))] fn visit_opaque_box(&self) -> bool { self.writer.write_char('@'); do self.get::<&managed::raw::BoxRepr> |b| { @@ -571,6 +573,16 @@ impl TyVisitor for ReprVisitor { 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. fn visit_constr(&self, _inner: *TyDesc) -> bool { fail!(); } @@ -581,7 +593,7 @@ impl TyVisitor for ReprVisitor { pub fn write_repr<T>(writer: @Writer, object: &T) { unsafe { let ptr = ptr::to_unsafe_ptr(object) as *c_void; - let tydesc = intrinsic::get_tydesc::<T>(); + let tydesc = get_tydesc::<T>(); let u = ReprVisitor(ptr, writer); let v = reflect::MovePtrAdaptor(u); visit_tydesc(tydesc, @v as @TyVisitor) diff --git a/src/libstd/rt/global_heap.rs b/src/libstd/rt/global_heap.rs index ce7ff87b445..1e9f9aab834 100644 --- a/src/libstd/rt/global_heap.rs +++ b/src/libstd/rt/global_heap.rs @@ -8,26 +8,22 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use sys::{TypeDesc, size_of}; +use sys::{size_of}; use libc::{c_void, size_t, uintptr_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 unstable::intrinsics::{atomic_xadd,atomic_xsub,TyDesc}; use ptr::null; -use intrinsic::TyDesc; -pub unsafe fn malloc(td: *TypeDesc, size: uint) -> *c_void { +pub unsafe fn malloc(td: *TyDesc, 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; diff --git a/src/libstd/sys.rs b/src/libstd/sys.rs index 79ea60cc224..a1d6342323c 100644 --- a/src/libstd/sys.rs +++ b/src/libstd/sys.rs @@ -17,23 +17,11 @@ use cast; use gc; use io; use libc; -use libc::{c_void, c_char, size_t}; +use libc::{c_char, size_t}; use repr; use str; use unstable::intrinsics; -pub type FreeGlue<'self> = &'self fn(*TypeDesc, *c_void); - -// Corresponds to runtime type_desc type -pub struct TypeDesc { - size: uint, - align: uint, - take_glue: uint, - drop_glue: uint, - free_glue: uint - // Remaining fields not listed -} - /// The representation of a Rust closure pub struct Closure { code: *(), @@ -51,23 +39,6 @@ pub mod rustrt { } } -/** - * Returns a pointer to a type descriptor. - * - * Useful for calling certain function in the Rust runtime or otherwise - * performing dark magick. - */ -#[inline] -pub fn get_type_desc<T>() -> *TypeDesc { - unsafe { intrinsics::get_tydesc::<T>() as *TypeDesc } -} - -/// Returns a pointer to a type descriptor. -#[inline] -pub fn get_type_desc_val<T>(_val: &T) -> *TypeDesc { - get_type_desc::<T>() -} - /// Returns the size of a type #[inline] pub fn size_of<T>() -> uint { diff --git a/src/libstd/unstable/exchange_alloc.rs b/src/libstd/unstable/exchange_alloc.rs index 3b35c2fb804..5c47901df48 100644 --- a/src/libstd/unstable/exchange_alloc.rs +++ b/src/libstd/unstable/exchange_alloc.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use sys::{TypeDesc, size_of}; +use sys::size_of; use libc::{c_void, size_t}; use c_malloc = libc::malloc; use c_free = libc::free; @@ -16,18 +16,18 @@ use managed::raw::{BoxHeaderRepr, BoxRepr}; use cast::transmute; use unstable::intrinsics::{atomic_xadd,atomic_xsub}; use ptr::null; +#[cfg(stage0)] use intrinsic::TyDesc; +#[cfg(not(stage0))] +use unstable::intrinsics::TyDesc; -pub unsafe fn malloc(td: *TypeDesc, size: uint) -> *c_void { +pub unsafe fn malloc(td: *TyDesc, 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; diff --git a/src/libstd/unstable/intrinsics.rs b/src/libstd/unstable/intrinsics.rs index 109f665e41d..1254a591293 100644 --- a/src/libstd/unstable/intrinsics.rs +++ b/src/libstd/unstable/intrinsics.rs @@ -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" { @@ -159,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. @@ -181,9 +308,8 @@ 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) -> (); + #[cfg(not(stage0))] + pub fn visit_tydesc(td: *TyDesc, tv: @TyVisitor); pub fn frame_address(f: &once fn(*u8)); diff --git a/src/libstd/vec.rs b/src/libstd/vec.rs index e39dd262cd9..72b58307849 100644 --- a/src/libstd/vec.rs +++ b/src/libstd/vec.rs @@ -30,6 +30,10 @@ use sys; use sys::size_of; use uint; use unstable::intrinsics; +#[cfg(stage0)] +use intrinsic::{get_tydesc}; +#[cfg(not(stage0))] +use unstable::intrinsics::{get_tydesc}; use vec; use util; @@ -37,19 +41,22 @@ use util; pub mod rustrt { use libc; - use sys; use vec::raw; + #[cfg(stage0)] + use intrinsic::{TyDesc}; + #[cfg(not(stage0))] + use unstable::intrinsics::{TyDesc}; #[abi = "cdecl"] pub extern { // These names are terrible. reserve_shared applies // to ~[] and reserve_shared_actual applies to @[]. #[fast_ffi] - unsafe fn vec_reserve_shared(t: *sys::TypeDesc, + unsafe fn vec_reserve_shared(t: *TyDesc, v: **raw::VecRepr, n: libc::size_t); #[fast_ffi] - unsafe fn vec_reserve_shared_actual(t: *sys::TypeDesc, + unsafe fn vec_reserve_shared_actual(t: *TyDesc, v: **raw::VecRepr, n: libc::size_t); } @@ -78,7 +85,7 @@ pub fn reserve<T>(v: &mut ~[T], n: uint) { if capacity(v) < n { unsafe { let ptr: **raw::VecRepr = cast::transmute(v); - let td = sys::get_type_desc::<T>(); + let td = get_tydesc::<T>(); if ((**ptr).box_header.ref_count == managed::raw::RC_MANAGED_UNIQUE) { rustrt::vec_reserve_shared_actual(td, ptr, n as libc::size_t); |
