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.
This commit is contained in:
commit
7aee5da08d
@ -41,30 +41,21 @@ use list::{MutList, MutCons, MutNil};
|
|||||||
use core::at_vec;
|
use core::at_vec;
|
||||||
use core::cast::{transmute, transmute_mut, transmute_mut_region};
|
use core::cast::{transmute, transmute_mut, transmute_mut_region};
|
||||||
use core::cast;
|
use core::cast;
|
||||||
use core::libc::size_t;
|
|
||||||
use core::ptr;
|
use core::ptr;
|
||||||
use core::sys::TypeDesc;
|
|
||||||
use core::sys;
|
use core::sys;
|
||||||
use core::uint;
|
use core::uint;
|
||||||
use core::vec;
|
use core::vec;
|
||||||
use core::unstable::intrinsics;
|
use core::unstable::intrinsics;
|
||||||
|
use core::unstable::intrinsics::{TyDesc};
|
||||||
|
|
||||||
pub mod rustrt {
|
#[cfg(not(stage0))]
|
||||||
use core::libc::size_t;
|
use core::unstable::intrinsics::{get_tydesc};
|
||||||
use core::sys::TypeDesc;
|
|
||||||
|
|
||||||
pub extern {
|
#[cfg(stage0)]
|
||||||
#[rust_stack]
|
unsafe fn get_tydesc<T>() -> *TyDesc {
|
||||||
unsafe fn rust_call_tydesc_glue(root: *u8,
|
intrinsics::get_tydesc::<T>() as *TyDesc
|
||||||
tydesc: *TypeDesc,
|
|
||||||
field: size_t);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// This probably belongs somewhere else. Needs to be kept in sync with
|
|
||||||
// changes to glue...
|
|
||||||
static tydesc_drop_glue_index: size_t = 3 as size_t;
|
|
||||||
|
|
||||||
// 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
|
||||||
// will always stay at 0.
|
// will always stay at 0.
|
||||||
@ -125,6 +116,19 @@ 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) {
|
||||||
@ -137,19 +141,18 @@ unsafe fn destroy_chunk(chunk: &Chunk) {
|
|||||||
let (tydesc, is_done) = un_bitpack_tydesc_ptr(*tydesc_data);
|
let (tydesc, is_done) = un_bitpack_tydesc_ptr(*tydesc_data);
|
||||||
let (size, align) = ((*tydesc).size, (*tydesc).align);
|
let (size, align) = ((*tydesc).size, (*tydesc).align);
|
||||||
|
|
||||||
let after_tydesc = idx + sys::size_of::<*TypeDesc>();
|
let after_tydesc = idx + sys::size_of::<*TyDesc>();
|
||||||
|
|
||||||
let start = round_up_to(after_tydesc, align);
|
let start = round_up_to(after_tydesc, align);
|
||||||
|
|
||||||
//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 {
|
||||||
rustrt::rust_call_tydesc_glue(
|
call_drop_glue(tydesc, ptr::offset(buf, start) as *i8);
|
||||||
ptr::offset(buf, start), tydesc, tydesc_drop_glue_index);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Find where the next tydesc lives
|
// Find where the next tydesc lives
|
||||||
idx = round_up_to(start + size, sys::pref_align_of::<*TypeDesc>());
|
idx = round_up_to(start + size, sys::pref_align_of::<*TyDesc>());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -158,12 +161,12 @@ unsafe fn destroy_chunk(chunk: &Chunk) {
|
|||||||
// is necessary in order to properly do cleanup if a failure occurs
|
// is necessary in order to properly do cleanup if a failure occurs
|
||||||
// during an initializer.
|
// during an initializer.
|
||||||
#[inline]
|
#[inline]
|
||||||
unsafe fn bitpack_tydesc_ptr(p: *TypeDesc, is_done: bool) -> uint {
|
unsafe fn bitpack_tydesc_ptr(p: *TyDesc, is_done: bool) -> uint {
|
||||||
let p_bits: uint = transmute(p);
|
let p_bits: uint = transmute(p);
|
||||||
p_bits | (is_done as uint)
|
p_bits | (is_done as uint)
|
||||||
}
|
}
|
||||||
#[inline]
|
#[inline]
|
||||||
unsafe fn un_bitpack_tydesc_ptr(p: uint) -> (*TypeDesc, bool) {
|
unsafe fn un_bitpack_tydesc_ptr(p: uint) -> (*TyDesc, bool) {
|
||||||
(transmute(p & !1), p & 1 == 1)
|
(transmute(p & !1), p & 1 == 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -203,7 +206,7 @@ impl Arena {
|
|||||||
#[inline]
|
#[inline]
|
||||||
fn alloc_pod<'a, T>(&'a mut self, op: &fn() -> T) -> &'a T {
|
fn alloc_pod<'a, T>(&'a mut self, op: &fn() -> T) -> &'a T {
|
||||||
unsafe {
|
unsafe {
|
||||||
let tydesc = sys::get_type_desc::<T>();
|
let tydesc = get_tydesc::<T>();
|
||||||
let ptr = self.alloc_pod_inner((*tydesc).size, (*tydesc).align);
|
let ptr = self.alloc_pod_inner((*tydesc).size, (*tydesc).align);
|
||||||
let ptr: *mut T = transmute(ptr);
|
let ptr: *mut T = transmute(ptr);
|
||||||
intrinsics::move_val_init(&mut (*ptr), op());
|
intrinsics::move_val_init(&mut (*ptr), op());
|
||||||
@ -231,13 +234,13 @@ impl Arena {
|
|||||||
let head = transmute_mut_region(&mut self.head);
|
let head = transmute_mut_region(&mut self.head);
|
||||||
|
|
||||||
let tydesc_start = head.fill;
|
let tydesc_start = head.fill;
|
||||||
let after_tydesc = head.fill + sys::size_of::<*TypeDesc>();
|
let after_tydesc = head.fill + sys::size_of::<*TyDesc>();
|
||||||
let start = round_up_to(after_tydesc, align);
|
let start = round_up_to(after_tydesc, align);
|
||||||
let end = start + n_bytes;
|
let end = start + n_bytes;
|
||||||
if end > at_vec::capacity(head.data) {
|
if end > at_vec::capacity(head.data) {
|
||||||
return self.alloc_nonpod_grow(n_bytes, align);
|
return self.alloc_nonpod_grow(n_bytes, align);
|
||||||
}
|
}
|
||||||
head.fill = round_up_to(end, sys::pref_align_of::<*TypeDesc>());
|
head.fill = round_up_to(end, sys::pref_align_of::<*TyDesc>());
|
||||||
|
|
||||||
//debug!("idx = %u, size = %u, align = %u, fill = %u",
|
//debug!("idx = %u, size = %u, align = %u, fill = %u",
|
||||||
// start, n_bytes, align, head.fill);
|
// start, n_bytes, align, head.fill);
|
||||||
@ -250,7 +253,7 @@ impl Arena {
|
|||||||
#[inline]
|
#[inline]
|
||||||
fn alloc_nonpod<'a, T>(&'a mut self, op: &fn() -> T) -> &'a T {
|
fn alloc_nonpod<'a, T>(&'a mut self, op: &fn() -> T) -> &'a T {
|
||||||
unsafe {
|
unsafe {
|
||||||
let tydesc = sys::get_type_desc::<T>();
|
let tydesc = get_tydesc::<T>();
|
||||||
let (ty_ptr, ptr) =
|
let (ty_ptr, ptr) =
|
||||||
self.alloc_nonpod_inner((*tydesc).size, (*tydesc).align);
|
self.alloc_nonpod_inner((*tydesc).size, (*tydesc).align);
|
||||||
let ty_ptr: *mut uint = transmute(ty_ptr);
|
let ty_ptr: *mut uint = transmute(ty_ptr);
|
||||||
|
@ -13,56 +13,62 @@
|
|||||||
#[allow(missing_doc)];
|
#[allow(missing_doc)];
|
||||||
|
|
||||||
use core::cast::transmute;
|
use core::cast::transmute;
|
||||||
use core::sys;
|
#[cfg(stage0)]
|
||||||
|
use intrinsic::{get_tydesc};
|
||||||
|
#[cfg(not(stage0))]
|
||||||
|
use core::unstable::intrinsics::{get_tydesc};
|
||||||
|
|
||||||
pub mod rustrt {
|
pub mod rustrt {
|
||||||
use core::sys;
|
#[cfg(stage0)]
|
||||||
|
use intrinsic::{TyDesc};
|
||||||
|
#[cfg(not(stage0))]
|
||||||
|
use core::unstable::intrinsics::{TyDesc};
|
||||||
|
|
||||||
#[abi = "cdecl"]
|
#[abi = "cdecl"]
|
||||||
pub extern {
|
pub extern {
|
||||||
pub unsafe fn debug_tydesc(td: *sys::TypeDesc);
|
pub unsafe fn debug_tydesc(td: *TyDesc);
|
||||||
pub unsafe fn debug_opaque(td: *sys::TypeDesc, x: *());
|
pub unsafe fn debug_opaque(td: *TyDesc, x: *());
|
||||||
pub unsafe fn debug_box(td: *sys::TypeDesc, x: *());
|
pub unsafe fn debug_box(td: *TyDesc, x: *());
|
||||||
pub unsafe fn debug_tag(td: *sys::TypeDesc, x: *());
|
pub unsafe fn debug_tag(td: *TyDesc, x: *());
|
||||||
pub unsafe fn debug_fn(td: *sys::TypeDesc, x: *());
|
pub unsafe fn debug_fn(td: *TyDesc, x: *());
|
||||||
pub unsafe fn debug_ptrcast(td: *sys::TypeDesc, x: *()) -> *();
|
pub unsafe fn debug_ptrcast(td: *TyDesc, x: *()) -> *();
|
||||||
pub unsafe fn rust_dbg_breakpoint();
|
pub unsafe fn rust_dbg_breakpoint();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn debug_tydesc<T>() {
|
pub fn debug_tydesc<T>() {
|
||||||
unsafe {
|
unsafe {
|
||||||
rustrt::debug_tydesc(sys::get_type_desc::<T>());
|
rustrt::debug_tydesc(get_tydesc::<T>());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn debug_opaque<T>(x: T) {
|
pub fn debug_opaque<T>(x: T) {
|
||||||
unsafe {
|
unsafe {
|
||||||
rustrt::debug_opaque(sys::get_type_desc::<T>(), transmute(&x));
|
rustrt::debug_opaque(get_tydesc::<T>(), transmute(&x));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn debug_box<T>(x: @T) {
|
pub fn debug_box<T>(x: @T) {
|
||||||
unsafe {
|
unsafe {
|
||||||
rustrt::debug_box(sys::get_type_desc::<T>(), transmute(&x));
|
rustrt::debug_box(get_tydesc::<T>(), transmute(&x));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn debug_tag<T>(x: T) {
|
pub fn debug_tag<T>(x: T) {
|
||||||
unsafe {
|
unsafe {
|
||||||
rustrt::debug_tag(sys::get_type_desc::<T>(), transmute(&x));
|
rustrt::debug_tag(get_tydesc::<T>(), transmute(&x));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn debug_fn<T>(x: T) {
|
pub fn debug_fn<T>(x: T) {
|
||||||
unsafe {
|
unsafe {
|
||||||
rustrt::debug_fn(sys::get_type_desc::<T>(), transmute(&x));
|
rustrt::debug_fn(get_tydesc::<T>(), transmute(&x));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub unsafe fn ptr_cast<T, U>(x: @T) -> @U {
|
pub unsafe fn ptr_cast<T, U>(x: @T) -> @U {
|
||||||
transmute(
|
transmute(
|
||||||
rustrt::debug_ptrcast(sys::get_type_desc::<T>(), transmute(x)))
|
rustrt::debug_ptrcast(get_tydesc::<T>(), transmute(x)))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Triggers a debugger breakpoint
|
/// Triggers a debugger breakpoint
|
||||||
|
@ -8,9 +8,6 @@
|
|||||||
// option. This file may not be copied, modified, or distributed
|
// option. This file may not be copied, modified, or distributed
|
||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
pub static rc_base_field_refcnt: uint = 0u;
|
pub static rc_base_field_refcnt: uint = 0u;
|
||||||
|
|
||||||
pub static task_field_refcnt: uint = 0u;
|
pub static task_field_refcnt: uint = 0u;
|
||||||
@ -49,9 +46,7 @@ pub static tydesc_field_take_glue: uint = 2u;
|
|||||||
pub static tydesc_field_drop_glue: uint = 3u;
|
pub static tydesc_field_drop_glue: uint = 3u;
|
||||||
pub static tydesc_field_free_glue: uint = 4u;
|
pub static tydesc_field_free_glue: uint = 4u;
|
||||||
pub static tydesc_field_visit_glue: uint = 5u;
|
pub static tydesc_field_visit_glue: uint = 5u;
|
||||||
pub static tydesc_field_shape: uint = 6u;
|
pub static n_tydesc_fields: uint = 6u;
|
||||||
pub static tydesc_field_shape_tables: uint = 7u;
|
|
||||||
pub static n_tydesc_fields: uint = 8u;
|
|
||||||
|
|
||||||
// The two halves of a closure: code and environment.
|
// The two halves of a closure: code and environment.
|
||||||
pub static fn_field_code: uint = 0u;
|
pub static fn_field_code: uint = 0u;
|
||||||
@ -71,14 +66,4 @@ pub static vec_elt_elems: uint = 2u;
|
|||||||
pub static slice_elt_base: uint = 0u;
|
pub static slice_elt_base: uint = 0u;
|
||||||
pub static slice_elt_len: uint = 1u;
|
pub static slice_elt_len: uint = 1u;
|
||||||
|
|
||||||
pub static worst_case_glue_call_args: uint = 7u;
|
|
||||||
|
|
||||||
pub static abi_version: uint = 1u;
|
pub static abi_version: uint = 1u;
|
||||||
|
|
||||||
pub fn memcpy_glue_name() -> ~str { return ~"rust_memcpy_glue"; }
|
|
||||||
|
|
||||||
pub fn bzero_glue_name() -> ~str { return ~"rust_bzero_glue"; }
|
|
||||||
|
|
||||||
pub fn yield_glue_name() -> ~str { return ~"rust_yield_glue"; }
|
|
||||||
|
|
||||||
pub fn no_op_type_glue_name() -> ~str { return ~"rust_no_op_type_glue"; }
|
|
||||||
|
@ -206,9 +206,6 @@ pub fn compile_rest(sess: Session,
|
|||||||
let mut crate = crate_opt.unwrap();
|
let mut crate = crate_opt.unwrap();
|
||||||
|
|
||||||
let (llcx, llmod, link_meta) = {
|
let (llcx, llmod, link_meta) = {
|
||||||
crate = time(time_passes, ~"intrinsic injection", ||
|
|
||||||
front::intrinsic_inject::inject_intrinsic(sess, crate));
|
|
||||||
|
|
||||||
crate = time(time_passes, ~"extra injection", ||
|
crate = time(time_passes, ~"extra injection", ||
|
||||||
front::std_inject::maybe_inject_libstd_ref(sess, crate));
|
front::std_inject::maybe_inject_libstd_ref(sess, crate));
|
||||||
|
|
||||||
|
@ -1,140 +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.
|
|
||||||
|
|
||||||
// NB: this file is include_str!'ed into the compiler, re-parsed
|
|
||||||
// and injected into each crate the compiler builds. Keep it small.
|
|
||||||
|
|
||||||
pub mod intrinsic {
|
|
||||||
#[allow(missing_doc)];
|
|
||||||
|
|
||||||
pub use intrinsic::rusti::visit_tydesc;
|
|
||||||
|
|
||||||
// FIXME (#3727): remove this when the interface has settled and the
|
|
||||||
// version in sys is no longer present.
|
|
||||||
pub fn get_tydesc<T>() -> *TyDesc {
|
|
||||||
unsafe {
|
|
||||||
rusti::get_tydesc::<T>() as *TyDesc
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct TyDesc {
|
|
||||||
size: uint,
|
|
||||||
align: uint
|
|
||||||
// Remaining fields not listed
|
|
||||||
}
|
|
||||||
|
|
||||||
pub enum Opaque { }
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub mod rusti {
|
|
||||||
use super::{TyDesc, TyVisitor};
|
|
||||||
|
|
||||||
#[abi = "rust-intrinsic"]
|
|
||||||
pub extern "rust-intrinsic" {
|
|
||||||
pub fn get_tydesc<T>() -> *();
|
|
||||||
pub fn visit_tydesc(td: *TyDesc, tv: @TyVisitor);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,47 +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 core::prelude::*;
|
|
||||||
|
|
||||||
use core::vec;
|
|
||||||
use driver::session::Session;
|
|
||||||
use syntax::parse;
|
|
||||||
use syntax::ast;
|
|
||||||
use syntax::codemap::spanned;
|
|
||||||
|
|
||||||
pub fn inject_intrinsic(sess: Session, crate: @ast::crate) -> @ast::crate {
|
|
||||||
let intrinsic_module = include_str!("intrinsic.rs").to_managed();
|
|
||||||
|
|
||||||
let item = parse::parse_item_from_source_str(@"<intrinsic>",
|
|
||||||
intrinsic_module,
|
|
||||||
/*bad*/copy sess.opts.cfg,
|
|
||||||
~[],
|
|
||||||
sess.parse_sess);
|
|
||||||
let item =
|
|
||||||
match item {
|
|
||||||
Some(i) => i,
|
|
||||||
None => {
|
|
||||||
sess.fatal("no item found in intrinsic module");
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
let items = vec::append(~[item], crate.node.module.items);
|
|
||||||
|
|
||||||
@spanned {
|
|
||||||
node: ast::crate_ {
|
|
||||||
module: ast::_mod {
|
|
||||||
items: items,
|
|
||||||
.. /*bad*/copy crate.node.module
|
|
||||||
},
|
|
||||||
.. /*bad*/copy crate.node
|
|
||||||
},
|
|
||||||
.. /*bad*/copy *crate
|
|
||||||
}
|
|
||||||
}
|
|
@ -76,16 +76,20 @@ pub enum LangItem {
|
|||||||
UnrecordBorrowFnLangItem, // 36
|
UnrecordBorrowFnLangItem, // 36
|
||||||
|
|
||||||
StartFnLangItem, // 37
|
StartFnLangItem, // 37
|
||||||
|
|
||||||
|
TyDescStructLangItem, // 38
|
||||||
|
TyVisitorTraitLangItem, // 39
|
||||||
|
OpaqueStructLangItem, // 40
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct LanguageItems {
|
pub struct LanguageItems {
|
||||||
items: [Option<def_id>, ..38]
|
items: [Option<def_id>, ..41]
|
||||||
}
|
}
|
||||||
|
|
||||||
impl LanguageItems {
|
impl LanguageItems {
|
||||||
pub fn new() -> LanguageItems {
|
pub fn new() -> LanguageItems {
|
||||||
LanguageItems {
|
LanguageItems {
|
||||||
items: [ None, ..38 ]
|
items: [ None, ..41 ]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -138,6 +142,10 @@ impl LanguageItems {
|
|||||||
|
|
||||||
37 => "start",
|
37 => "start",
|
||||||
|
|
||||||
|
38 => "ty_desc",
|
||||||
|
39 => "ty_visitor",
|
||||||
|
40 => "opaque",
|
||||||
|
|
||||||
_ => "???"
|
_ => "???"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -262,6 +270,15 @@ impl LanguageItems {
|
|||||||
pub fn start_fn(&const self) -> def_id {
|
pub fn start_fn(&const self) -> def_id {
|
||||||
self.items[StartFnLangItem as uint].get()
|
self.items[StartFnLangItem as uint].get()
|
||||||
}
|
}
|
||||||
|
pub fn ty_desc(&const self) -> def_id {
|
||||||
|
self.items[TyDescStructLangItem as uint].get()
|
||||||
|
}
|
||||||
|
pub fn ty_visitor(&const self) -> def_id {
|
||||||
|
self.items[TyVisitorTraitLangItem as uint].get()
|
||||||
|
}
|
||||||
|
pub fn opaque(&const self) -> def_id {
|
||||||
|
self.items[OpaqueStructLangItem as uint].get()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn LanguageItemCollector(crate: @crate,
|
fn LanguageItemCollector(crate: @crate,
|
||||||
@ -313,6 +330,9 @@ fn LanguageItemCollector(crate: @crate,
|
|||||||
item_refs.insert(@"record_borrow", RecordBorrowFnLangItem as uint);
|
item_refs.insert(@"record_borrow", RecordBorrowFnLangItem as uint);
|
||||||
item_refs.insert(@"unrecord_borrow", UnrecordBorrowFnLangItem as uint);
|
item_refs.insert(@"unrecord_borrow", UnrecordBorrowFnLangItem as uint);
|
||||||
item_refs.insert(@"start", StartFnLangItem as uint);
|
item_refs.insert(@"start", StartFnLangItem as uint);
|
||||||
|
item_refs.insert(@"ty_desc", TyDescStructLangItem as uint);
|
||||||
|
item_refs.insert(@"ty_visitor", TyVisitorTraitLangItem as uint);
|
||||||
|
item_refs.insert(@"opaque", OpaqueStructLangItem as uint);
|
||||||
|
|
||||||
LanguageItemCollector {
|
LanguageItemCollector {
|
||||||
crate: crate,
|
crate: crate,
|
||||||
|
@ -681,9 +681,12 @@ pub fn trans_intrinsic(ccx: @mut CrateContext,
|
|||||||
let static_ti = get_tydesc(ccx, tp_ty);
|
let static_ti = get_tydesc(ccx, tp_ty);
|
||||||
glue::lazily_emit_all_tydesc_glue(ccx, static_ti);
|
glue::lazily_emit_all_tydesc_glue(ccx, static_ti);
|
||||||
|
|
||||||
// FIXME (#3727): change this to ccx.tydesc_ty.ptr_to() when the
|
// FIXME (#3730): ideally this shouldn't need a cast,
|
||||||
// core::sys copy of the get_tydesc interface dies off.
|
// but there's a circularity between translating rust types to llvm
|
||||||
let td = PointerCast(bcx, static_ti.tydesc, Type::nil().ptr_to());
|
// types and having a tydesc type available. So I can't directly access
|
||||||
|
// the llvm type of intrinsic::TyDesc struct.
|
||||||
|
let userland_tydesc_ty = type_of::type_of(ccx, output_type);
|
||||||
|
let td = PointerCast(bcx, static_ti.tydesc, userland_tydesc_ty);
|
||||||
Store(bcx, td, fcx.llretptr.get());
|
Store(bcx, td, fcx.llretptr.get());
|
||||||
}
|
}
|
||||||
"init" => {
|
"init" => {
|
||||||
|
@ -232,7 +232,7 @@ pub fn lazily_emit_tydesc_glue(ccx: @mut CrateContext,
|
|||||||
field: uint,
|
field: uint,
|
||||||
ti: @mut tydesc_info) {
|
ti: @mut tydesc_info) {
|
||||||
let _icx = push_ctxt("lazily_emit_tydesc_glue");
|
let _icx = push_ctxt("lazily_emit_tydesc_glue");
|
||||||
let llfnty = type_of_glue_fn(ccx);
|
let llfnty = Type::glue_fn();
|
||||||
|
|
||||||
if lazily_emit_simplified_tydesc_glue(ccx, field, ti) {
|
if lazily_emit_simplified_tydesc_glue(ccx, field, ti) {
|
||||||
return;
|
return;
|
||||||
@ -338,9 +338,7 @@ pub fn call_tydesc_glue_full(bcx: block,
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
Call(bcx, llfn, [C_null(Type::nil().ptr_to()),
|
Call(bcx, llfn, [C_null(Type::nil().ptr_to()), llrawptr]);
|
||||||
C_null(bcx.ccx().tydesc_type.ptr_to().ptr_to()),
|
|
||||||
llrawptr]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// See [Note-arg-mode]
|
// See [Note-arg-mode]
|
||||||
@ -680,7 +678,7 @@ pub fn make_generic_glue_inner(ccx: @mut CrateContext,
|
|||||||
|
|
||||||
let bcx = top_scope_block(fcx, None);
|
let bcx = top_scope_block(fcx, None);
|
||||||
let lltop = bcx.llbb;
|
let lltop = bcx.llbb;
|
||||||
let rawptr0_arg = fcx.arg_pos(1u);
|
let rawptr0_arg = fcx.arg_pos(0u);
|
||||||
let llrawptr0 = unsafe { llvm::LLVMGetParam(llfn, rawptr0_arg as c_uint) };
|
let llrawptr0 = unsafe { llvm::LLVMGetParam(llfn, rawptr0_arg as c_uint) };
|
||||||
let llty = type_of(ccx, t);
|
let llty = type_of(ccx, t);
|
||||||
let llrawptr0 = PointerCast(bcx, llrawptr0, llty.ptr_to());
|
let llrawptr0 = PointerCast(bcx, llrawptr0, llty.ptr_to());
|
||||||
@ -715,7 +713,7 @@ pub fn emit_tydescs(ccx: &mut CrateContext) {
|
|||||||
let _icx = push_ctxt("emit_tydescs");
|
let _icx = push_ctxt("emit_tydescs");
|
||||||
// As of this point, allow no more tydescs to be created.
|
// As of this point, allow no more tydescs to be created.
|
||||||
ccx.finished_tydescs = true;
|
ccx.finished_tydescs = true;
|
||||||
let glue_fn_ty = Type::generic_glue_fn(ccx);
|
let glue_fn_ty = Type::generic_glue_fn(ccx).ptr_to();
|
||||||
let tyds = &mut ccx.tydescs;
|
let tyds = &mut ccx.tydescs;
|
||||||
for tyds.each_value |&val| {
|
for tyds.each_value |&val| {
|
||||||
let ti = val;
|
let ti = val;
|
||||||
@ -765,19 +763,13 @@ pub fn emit_tydescs(ccx: &mut CrateContext) {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
let shape = C_null(Type::i8p());
|
|
||||||
let shape_tables = C_null(Type::i8p());
|
|
||||||
|
|
||||||
let tydesc = C_named_struct(ccx.tydesc_type,
|
let tydesc = C_named_struct(ccx.tydesc_type,
|
||||||
[ti.size, // size
|
[ti.size, // size
|
||||||
ti.align, // align
|
ti.align, // align
|
||||||
take_glue, // take_glue
|
take_glue, // take_glue
|
||||||
drop_glue, // drop_glue
|
drop_glue, // drop_glue
|
||||||
free_glue, // free_glue
|
free_glue, // free_glue
|
||||||
visit_glue, // visit_glue
|
visit_glue]); // visit_glue
|
||||||
shape, // shape
|
|
||||||
shape_tables]); // shape_tables
|
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
let gvar = ti.tydesc;
|
let gvar = ti.tydesc;
|
||||||
@ -788,8 +780,3 @@ pub fn emit_tydescs(ccx: &mut CrateContext) {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
fn type_of_glue_fn(ccx: &CrateContext) -> Type {
|
|
||||||
let tydescpp = ccx.tydesc_type.ptr_to().ptr_to();
|
|
||||||
Type::func([ Type::nil().ptr_to(), tydescpp, Type::i8p() ], &Type::void())
|
|
||||||
}
|
|
||||||
|
@ -274,9 +274,7 @@ impl Reflector {
|
|||||||
let repr = adt::represent_type(bcx.ccx(), t);
|
let repr = adt::represent_type(bcx.ccx(), t);
|
||||||
let variants = ty::substd_enum_variants(ccx.tcx, did, substs);
|
let variants = ty::substd_enum_variants(ccx.tcx, did, substs);
|
||||||
let llptrty = type_of(ccx, t).ptr_to();
|
let llptrty = type_of(ccx, t).ptr_to();
|
||||||
let (_, opaquety) =
|
let opaquety = ty::get_opaque_ty(ccx.tcx);
|
||||||
ccx.tcx.intrinsic_defs.find_copy(&ccx.sess.ident_of("Opaque"))
|
|
||||||
.expect("Failed to resolve intrinsic::Opaque");
|
|
||||||
let opaqueptrty = ty::mk_ptr(ccx.tcx, ty::mt { ty: opaquety, mutbl: ast::m_imm });
|
let opaqueptrty = ty::mk_ptr(ccx.tcx, ty::mt { ty: opaquety, mutbl: ast::m_imm });
|
||||||
|
|
||||||
let make_get_disr = || {
|
let make_get_disr = || {
|
||||||
@ -373,10 +371,8 @@ pub fn emit_calls_to_trait_visit_ty(bcx: block,
|
|||||||
visitor_val: ValueRef,
|
visitor_val: ValueRef,
|
||||||
visitor_trait_id: def_id)
|
visitor_trait_id: def_id)
|
||||||
-> block {
|
-> block {
|
||||||
use syntax::parse::token::special_idents::tydesc;
|
|
||||||
let final = sub_block(bcx, "final");
|
let final = sub_block(bcx, "final");
|
||||||
assert!(bcx.ccx().tcx.intrinsic_defs.contains_key(&tydesc));
|
let tydesc_ty = ty::get_tydesc_ty(bcx.ccx().tcx);
|
||||||
let (_, tydesc_ty) = bcx.ccx().tcx.intrinsic_defs.get_copy(&tydesc);
|
|
||||||
let tydesc_ty = type_of(bcx.ccx(), tydesc_ty);
|
let tydesc_ty = type_of(bcx.ccx(), tydesc_ty);
|
||||||
let mut r = Reflector {
|
let mut r = Reflector {
|
||||||
visitor_val: visitor_val,
|
visitor_val: visitor_val,
|
||||||
|
@ -20,7 +20,6 @@ use middle::trans::base;
|
|||||||
|
|
||||||
use syntax::ast;
|
use syntax::ast;
|
||||||
use syntax::abi::{Architecture, X86, X86_64, Arm, Mips};
|
use syntax::abi::{Architecture, X86, X86_64, Arm, Mips};
|
||||||
use back::abi;
|
|
||||||
|
|
||||||
use core::vec;
|
use core::vec;
|
||||||
use core::cast;
|
use core::cast;
|
||||||
@ -189,25 +188,26 @@ impl Type {
|
|||||||
None => ()
|
None => ()
|
||||||
}
|
}
|
||||||
|
|
||||||
let ty = cx.tydesc_type.get_field(abi::tydesc_field_drop_glue);
|
let ty = Type::glue_fn();
|
||||||
cx.tn.associate_type("glue_fn", &ty);
|
cx.tn.associate_type("glue_fn", &ty);
|
||||||
|
|
||||||
return ty;
|
return ty;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn glue_fn() -> Type {
|
||||||
|
Type::func([ Type::nil().ptr_to(), Type::i8p() ],
|
||||||
|
&Type::void())
|
||||||
|
}
|
||||||
|
|
||||||
pub fn tydesc(arch: Architecture) -> Type {
|
pub fn tydesc(arch: Architecture) -> Type {
|
||||||
let mut tydesc = Type::named_struct("tydesc");
|
let mut tydesc = Type::named_struct("tydesc");
|
||||||
let tydescpp = tydesc.ptr_to().ptr_to();
|
let glue_fn_ty = Type::glue_fn().ptr_to();
|
||||||
let pvoid = Type::i8p();
|
|
||||||
let glue_fn_ty = Type::func([ Type::nil().ptr_to(), tydescpp, pvoid ],
|
|
||||||
&Type::void()).ptr_to();
|
|
||||||
|
|
||||||
let int_ty = Type::int(arch);
|
let int_ty = Type::int(arch);
|
||||||
|
|
||||||
let elems = [
|
let elems = [
|
||||||
int_ty, int_ty,
|
int_ty, int_ty,
|
||||||
glue_fn_ty, glue_fn_ty, glue_fn_ty, glue_fn_ty,
|
glue_fn_ty, glue_fn_ty, glue_fn_ty, glue_fn_ty
|
||||||
pvoid, pvoid
|
|
||||||
];
|
];
|
||||||
|
|
||||||
tydesc.set_struct_body(elems, false);
|
tydesc.set_struct_body(elems, false);
|
||||||
@ -265,10 +265,6 @@ impl Type {
|
|||||||
cx.int_type
|
cx.int_type
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn captured_tydescs(ctx: &CrateContext, num: uint) -> Type {
|
|
||||||
Type::struct_(vec::from_elem(num, ctx.tydesc_type.ptr_to()), false)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn opaque_trait(ctx: &CrateContext, store: ty::TraitStore) -> Type {
|
pub fn opaque_trait(ctx: &CrateContext, store: ty::TraitStore) -> Type {
|
||||||
let tydesc_ptr = ctx.tydesc_type.ptr_to();
|
let tydesc_ptr = ctx.tydesc_type.ptr_to();
|
||||||
match store {
|
match store {
|
||||||
|
@ -44,7 +44,6 @@ use syntax::attr;
|
|||||||
use syntax::codemap::span;
|
use syntax::codemap::span;
|
||||||
use syntax::codemap;
|
use syntax::codemap;
|
||||||
use syntax::parse::token;
|
use syntax::parse::token;
|
||||||
use syntax::parse::token::special_idents;
|
|
||||||
use syntax::{ast, ast_map};
|
use syntax::{ast, ast_map};
|
||||||
use syntax::opt_vec::OptVec;
|
use syntax::opt_vec::OptVec;
|
||||||
use syntax::opt_vec;
|
use syntax::opt_vec;
|
||||||
@ -276,8 +275,7 @@ struct ctxt_ {
|
|||||||
trait_defs: @mut HashMap<def_id, @TraitDef>,
|
trait_defs: @mut HashMap<def_id, @TraitDef>,
|
||||||
|
|
||||||
items: ast_map::map,
|
items: ast_map::map,
|
||||||
intrinsic_defs: @mut HashMap<ast::ident, (ast::def_id, t)>,
|
intrinsic_defs: @mut HashMap<ast::def_id, t>,
|
||||||
intrinsic_traits: @mut HashMap<ast::ident, @TraitRef>,
|
|
||||||
freevars: freevars::freevar_map,
|
freevars: freevars::freevar_map,
|
||||||
tcache: type_cache,
|
tcache: type_cache,
|
||||||
rcache: creader_cache,
|
rcache: creader_cache,
|
||||||
@ -954,7 +952,6 @@ pub fn mk_ctxt(s: session::Session,
|
|||||||
node_type_substs: @mut HashMap::new(),
|
node_type_substs: @mut HashMap::new(),
|
||||||
trait_refs: @mut HashMap::new(),
|
trait_refs: @mut HashMap::new(),
|
||||||
trait_defs: @mut HashMap::new(),
|
trait_defs: @mut HashMap::new(),
|
||||||
intrinsic_traits: @mut HashMap::new(),
|
|
||||||
items: amap,
|
items: amap,
|
||||||
intrinsic_defs: @mut HashMap::new(),
|
intrinsic_defs: @mut HashMap::new(),
|
||||||
freevars: freevars,
|
freevars: freevars,
|
||||||
@ -4469,10 +4466,26 @@ pub fn get_impl_id(tcx: ctxt, trait_id: def_id, self_ty: t) -> def_id {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_tydesc_ty(tcx: ctxt) -> t {
|
||||||
|
let tydesc_lang_item = tcx.lang_items.ty_desc();
|
||||||
|
tcx.intrinsic_defs.find_copy(&tydesc_lang_item)
|
||||||
|
.expect("Failed to resolve TyDesc")
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_opaque_ty(tcx: ctxt) -> t {
|
||||||
|
let opaque_lang_item = tcx.lang_items.opaque();
|
||||||
|
tcx.intrinsic_defs.find_copy(&opaque_lang_item)
|
||||||
|
.expect("Failed to resolve Opaque")
|
||||||
|
}
|
||||||
|
|
||||||
pub fn visitor_object_ty(tcx: ctxt) -> (@TraitRef, t) {
|
pub fn visitor_object_ty(tcx: ctxt) -> (@TraitRef, t) {
|
||||||
let ty_visitor_name = special_idents::ty_visitor;
|
let substs = substs {
|
||||||
assert!(tcx.intrinsic_traits.contains_key(&ty_visitor_name));
|
self_r: None,
|
||||||
let trait_ref = tcx.intrinsic_traits.get_copy(&ty_visitor_name);
|
self_ty: None,
|
||||||
|
tps: ~[]
|
||||||
|
};
|
||||||
|
let trait_lang_item = tcx.lang_items.ty_visitor();
|
||||||
|
let trait_ref = @TraitRef { def_id: trait_lang_item, substs: substs };
|
||||||
(trait_ref,
|
(trait_ref,
|
||||||
mk_trait(tcx, trait_ref.def_id, copy trait_ref.substs,
|
mk_trait(tcx, trait_ref.def_id, copy trait_ref.substs,
|
||||||
BoxTraitStore, ast::m_imm, EmptyBuiltinBounds()))
|
BoxTraitStore, ast::m_imm, EmptyBuiltinBounds()))
|
||||||
|
@ -3506,13 +3506,15 @@ pub fn check_intrinsic_type(ccx: @mut CrateCtxt, it: @ast::foreign_item) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
"get_tydesc" => {
|
"get_tydesc" => {
|
||||||
// FIXME (#3730): return *intrinsic::tydesc, not *()
|
let tydesc_ty = ty::get_tydesc_ty(ccx.tcx);
|
||||||
(1u, ~[], ty::mk_nil_ptr(ccx.tcx))
|
let td_ptr = ty::mk_ptr(ccx.tcx, ty::mt {
|
||||||
|
ty: tydesc_ty,
|
||||||
|
mutbl: ast::m_imm
|
||||||
|
});
|
||||||
|
(1u, ~[], td_ptr)
|
||||||
}
|
}
|
||||||
"visit_tydesc" => {
|
"visit_tydesc" => {
|
||||||
let tydesc_name = special_idents::tydesc;
|
let tydesc_ty = ty::get_tydesc_ty(ccx.tcx);
|
||||||
assert!(tcx.intrinsic_defs.contains_key(&tydesc_name));
|
|
||||||
let (_, tydesc_ty) = tcx.intrinsic_defs.get_copy(&tydesc_name);
|
|
||||||
let (_, visitor_object_ty) = ty::visitor_object_ty(tcx);
|
let (_, visitor_object_ty) = ty::visitor_object_ty(tcx);
|
||||||
let td_ptr = ty::mk_ptr(ccx.tcx, ty::mt {
|
let td_ptr = ty::mk_ptr(ccx.tcx, ty::mt {
|
||||||
ty: tydesc_ty,
|
ty: tydesc_ty,
|
||||||
|
@ -62,55 +62,16 @@ use syntax::opt_vec::OptVec;
|
|||||||
use syntax::opt_vec;
|
use syntax::opt_vec;
|
||||||
|
|
||||||
pub fn collect_item_types(ccx: @mut CrateCtxt, crate: @ast::crate) {
|
pub fn collect_item_types(ccx: @mut CrateCtxt, crate: @ast::crate) {
|
||||||
|
fn collect_intrinsic_type(ccx: @mut CrateCtxt,
|
||||||
// FIXME (#2592): hooking into the "intrinsic" root module is crude.
|
lang_item: ast::def_id) {
|
||||||
// There ought to be a better approach. Attributes?
|
let ty::ty_param_bounds_and_ty { ty: ty, _ } =
|
||||||
|
ccx.get_item_ty(lang_item);
|
||||||
for crate.node.module.items.iter().advance |crate_item| {
|
ccx.tcx.intrinsic_defs.insert(lang_item, ty);
|
||||||
if crate_item.ident
|
|
||||||
== ::syntax::parse::token::special_idents::intrinsic {
|
|
||||||
|
|
||||||
match crate_item.node {
|
|
||||||
ast::item_mod(ref m) => {
|
|
||||||
for m.items.iter().advance |intrinsic_item| {
|
|
||||||
let def_id = ast::def_id { crate: ast::local_crate,
|
|
||||||
node: intrinsic_item.id };
|
|
||||||
let substs = substs {
|
|
||||||
self_r: None,
|
|
||||||
self_ty: None,
|
|
||||||
tps: ~[]
|
|
||||||
};
|
|
||||||
|
|
||||||
match intrinsic_item.node {
|
|
||||||
ast::item_trait(*) => {
|
|
||||||
let tref = @ty::TraitRef {def_id: def_id,
|
|
||||||
substs: substs};
|
|
||||||
ccx.tcx.intrinsic_traits.insert
|
|
||||||
(intrinsic_item.ident, tref);
|
|
||||||
}
|
|
||||||
|
|
||||||
ast::item_enum(*) => {
|
|
||||||
let ty = ty::mk_enum(ccx.tcx, def_id, substs);
|
|
||||||
ccx.tcx.intrinsic_defs.insert
|
|
||||||
(intrinsic_item.ident, (def_id, ty));
|
|
||||||
}
|
|
||||||
|
|
||||||
ast::item_struct(*) => {
|
|
||||||
let ty = ty::mk_struct(ccx.tcx, def_id, substs);
|
|
||||||
ccx.tcx.intrinsic_defs.insert
|
|
||||||
(intrinsic_item.ident, (def_id, ty));
|
|
||||||
}
|
|
||||||
|
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => { }
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
collect_intrinsic_type(ccx, ccx.tcx.lang_items.ty_desc());
|
||||||
|
collect_intrinsic_type(ccx, ccx.tcx.lang_items.opaque());
|
||||||
|
|
||||||
visit::visit_crate(
|
visit::visit_crate(
|
||||||
crate, ((),
|
crate, ((),
|
||||||
visit::mk_simple_visitor(@visit::SimpleVisitor {
|
visit::mk_simple_visitor(@visit::SimpleVisitor {
|
||||||
|
@ -86,7 +86,6 @@ pub mod front {
|
|||||||
pub mod config;
|
pub mod config;
|
||||||
pub mod test;
|
pub mod test;
|
||||||
pub mod std_inject;
|
pub mod std_inject;
|
||||||
pub mod intrinsic_inject;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub mod back {
|
pub mod back {
|
||||||
|
@ -25,13 +25,16 @@ use vec::ImmutableVector;
|
|||||||
|
|
||||||
pub mod rustrt {
|
pub mod rustrt {
|
||||||
use libc;
|
use libc;
|
||||||
use sys;
|
|
||||||
use vec;
|
use vec;
|
||||||
|
#[cfg(stage0)]
|
||||||
|
use intrinsic::{TyDesc};
|
||||||
|
#[cfg(not(stage0))]
|
||||||
|
use unstable::intrinsics::{TyDesc};
|
||||||
|
|
||||||
#[abi = "cdecl"]
|
#[abi = "cdecl"]
|
||||||
#[link_name = "rustrt"]
|
#[link_name = "rustrt"]
|
||||||
pub extern {
|
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,
|
v: **vec::raw::VecRepr,
|
||||||
n: libc::size_t);
|
n: libc::size_t);
|
||||||
}
|
}
|
||||||
@ -197,6 +200,10 @@ pub mod raw {
|
|||||||
use uint;
|
use uint;
|
||||||
use unstable::intrinsics::{move_val_init};
|
use unstable::intrinsics::{move_val_init};
|
||||||
use vec;
|
use vec;
|
||||||
|
#[cfg(stage0)]
|
||||||
|
use intrinsic::{get_tydesc};
|
||||||
|
#[cfg(not(stage0))]
|
||||||
|
use unstable::intrinsics::{get_tydesc};
|
||||||
|
|
||||||
pub type VecRepr = vec::raw::VecRepr;
|
pub type VecRepr = vec::raw::VecRepr;
|
||||||
pub type SliceRepr = vec::raw::SliceRepr;
|
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
|
// Only make the (slow) call into the runtime if we have to
|
||||||
if capacity(*v) < n {
|
if capacity(*v) < n {
|
||||||
let ptr: **VecRepr = transmute(v);
|
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);
|
ptr, n as libc::size_t);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,24 +10,19 @@
|
|||||||
|
|
||||||
#[doc(hidden)];
|
#[doc(hidden)];
|
||||||
|
|
||||||
use libc::{c_char, c_void, intptr_t, uintptr_t};
|
use libc::{c_char, intptr_t, uintptr_t};
|
||||||
use ptr::mut_null;
|
use ptr::{mut_null};
|
||||||
use repr::BoxRepr;
|
use repr::BoxRepr;
|
||||||
use sys::TypeDesc;
|
|
||||||
use cast::transmute;
|
use cast::transmute;
|
||||||
|
use unstable::intrinsics::TyDesc;
|
||||||
#[cfg(not(test))] use unstable::lang::clear_task_borrow_list;
|
#[cfg(not(test))] use unstable::lang::clear_task_borrow_list;
|
||||||
|
|
||||||
#[cfg(not(test))] use ptr::to_unsafe_ptr;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Runtime structures
|
* Runtime structures
|
||||||
*
|
*
|
||||||
* NB: These must match the representation in the C++ runtime.
|
* 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;
|
type TaskID = uintptr_t;
|
||||||
|
|
||||||
struct StackSegment { priv opaque: () }
|
struct StackSegment { priv opaque: () }
|
||||||
@ -164,6 +159,19 @@ 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.
|
||||||
#[cfg(not(test))]
|
#[cfg(not(test))]
|
||||||
#[lang="annihilate"]
|
#[lang="annihilate"]
|
||||||
@ -205,9 +213,9 @@ pub unsafe fn annihilate() {
|
|||||||
// callback, as the original value may have been freed.
|
// callback, as the original value may have been freed.
|
||||||
for each_live_alloc(false) |box, uniq| {
|
for each_live_alloc(false) |box, uniq| {
|
||||||
if !uniq {
|
if !uniq {
|
||||||
let tydesc: *TypeDesc = transmute(copy (*box).header.type_desc);
|
let tydesc = (*box).header.type_desc;
|
||||||
let drop_glue: DropGlue = transmute(((*tydesc).drop_glue, 0));
|
let data = transmute(&(*box).data);
|
||||||
drop_glue(to_unsafe_ptr(&tydesc), transmute(&(*box).data));
|
call_drop_glue(tydesc, data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -40,12 +40,13 @@ with destructors.
|
|||||||
use cast;
|
use cast;
|
||||||
use container::{Map, Set};
|
use container::{Map, Set};
|
||||||
use io;
|
use io;
|
||||||
use libc::{size_t, uintptr_t};
|
use libc::{uintptr_t};
|
||||||
use option::{None, Option, Some};
|
use option::{None, Option, Some};
|
||||||
use ptr;
|
use ptr;
|
||||||
use hashmap::HashSet;
|
use hashmap::HashSet;
|
||||||
use stackwalk::walk_stack;
|
use stackwalk::walk_stack;
|
||||||
use sys;
|
use sys;
|
||||||
|
use unstable::intrinsics::{TyDesc};
|
||||||
|
|
||||||
pub use stackwalk::Word;
|
pub use stackwalk::Word;
|
||||||
|
|
||||||
@ -58,17 +59,11 @@ pub struct StackSegment {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub mod rustrt {
|
pub mod rustrt {
|
||||||
use libc::size_t;
|
|
||||||
use stackwalk::Word;
|
use stackwalk::Word;
|
||||||
use super::StackSegment;
|
use super::StackSegment;
|
||||||
|
|
||||||
#[link_name = "rustrt"]
|
#[link_name = "rustrt"]
|
||||||
pub extern {
|
pub extern {
|
||||||
#[rust_stack]
|
|
||||||
pub unsafe fn rust_call_tydesc_glue(root: *Word,
|
|
||||||
tydesc: *Word,
|
|
||||||
field: size_t);
|
|
||||||
|
|
||||||
#[rust_stack]
|
#[rust_stack]
|
||||||
pub unsafe fn rust_gc_metadata() -> *Word;
|
pub unsafe fn rust_gc_metadata() -> *Word;
|
||||||
|
|
||||||
@ -125,7 +120,7 @@ unsafe fn is_safe_point(pc: *Word) -> Option<SafePoint> {
|
|||||||
return None;
|
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
|
// Walks the list of roots for the given safe point, and calls visitor
|
||||||
// on each root.
|
// 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 stack_roots: *u32 = bump(sp_meta, 2);
|
||||||
let reg_roots: *u8 = bump(stack_roots, num_stack_roots);
|
let reg_roots: *u8 = bump(stack_roots, num_stack_roots);
|
||||||
let addrspaces: *Word = align_to_pointer(bump(reg_roots, num_reg_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
|
// Stack roots
|
||||||
let mut sri = 0;
|
let mut sri = 0;
|
||||||
@ -321,6 +316,19 @@ 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.
|
||||||
@ -364,7 +372,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 {
|
||||||
rustrt::rust_call_tydesc_glue(*root, tydesc, 3 as size_t);
|
call_drop_glue(tydesc, *root as *i8);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,7 @@ use ptr::to_unsafe_ptr;
|
|||||||
#[cfg(not(test))] use cmp::{Eq, Ord};
|
#[cfg(not(test))] use cmp::{Eq, Ord};
|
||||||
|
|
||||||
pub mod raw {
|
pub mod raw {
|
||||||
use intrinsic::TyDesc;
|
use std::unstable::intrinsics::TyDesc;
|
||||||
|
|
||||||
pub static RC_EXCHANGE_UNIQUE : uint = (-1) as uint;
|
pub static RC_EXCHANGE_UNIQUE : uint = (-1) as uint;
|
||||||
pub static RC_MANAGED_UNIQUE : uint = (-2) as uint;
|
pub static RC_MANAGED_UNIQUE : uint = (-2) as uint;
|
||||||
|
@ -16,8 +16,10 @@ Runtime type reflection
|
|||||||
|
|
||||||
#[allow(missing_doc)];
|
#[allow(missing_doc)];
|
||||||
|
|
||||||
use intrinsic::{TyDesc, TyVisitor};
|
#[cfg(stage0)]
|
||||||
use intrinsic::Opaque;
|
use intrinsic::{Opaque, TyDesc, TyVisitor};
|
||||||
|
#[cfg(not(stage0))]
|
||||||
|
use unstable::intrinsics::{Opaque, TyDesc, TyVisitor};
|
||||||
use libc::c_void;
|
use libc::c_void;
|
||||||
use sys;
|
use sys;
|
||||||
use vec;
|
use vec;
|
||||||
|
@ -19,9 +19,6 @@ More runtime type reflection
|
|||||||
use cast::transmute;
|
use cast::transmute;
|
||||||
use char;
|
use char;
|
||||||
use container::Container;
|
use container::Container;
|
||||||
use intrinsic;
|
|
||||||
use intrinsic::{TyDesc, TyVisitor, visit_tydesc};
|
|
||||||
use intrinsic::Opaque;
|
|
||||||
use io::{Writer, WriterUtil};
|
use io::{Writer, WriterUtil};
|
||||||
use iterator::IteratorUtil;
|
use iterator::IteratorUtil;
|
||||||
use libc::c_void;
|
use libc::c_void;
|
||||||
@ -34,6 +31,10 @@ 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};
|
||||||
|
|
||||||
#[cfg(test)] use io;
|
#[cfg(test)] use io;
|
||||||
|
|
||||||
@ -564,6 +565,7 @@ 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,6 +573,16 @@ 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!(); }
|
||||||
@ -581,7 +593,7 @@ impl TyVisitor for ReprVisitor {
|
|||||||
pub fn write_repr<T>(writer: @Writer, object: &T) {
|
pub fn write_repr<T>(writer: @Writer, object: &T) {
|
||||||
unsafe {
|
unsafe {
|
||||||
let ptr = ptr::to_unsafe_ptr(object) as *c_void;
|
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 u = ReprVisitor(ptr, writer);
|
||||||
let v = reflect::MovePtrAdaptor(u);
|
let v = reflect::MovePtrAdaptor(u);
|
||||||
visit_tydesc(tydesc, @v as @TyVisitor)
|
visit_tydesc(tydesc, @v as @TyVisitor)
|
||||||
|
@ -8,26 +8,22 @@
|
|||||||
// option. This file may not be copied, modified, or distributed
|
// option. This file may not be copied, modified, or distributed
|
||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
use sys::{TypeDesc, size_of};
|
use sys::{size_of};
|
||||||
use libc::{c_void, size_t, uintptr_t};
|
use libc::{c_void, size_t, uintptr_t};
|
||||||
use c_malloc = libc::malloc;
|
use c_malloc = libc::malloc;
|
||||||
use c_free = libc::free;
|
use c_free = libc::free;
|
||||||
use managed::raw::{BoxHeaderRepr, BoxRepr};
|
use managed::raw::{BoxHeaderRepr, BoxRepr};
|
||||||
use cast::transmute;
|
use cast::transmute;
|
||||||
use unstable::intrinsics::{atomic_xadd,atomic_xsub};
|
use unstable::intrinsics::{atomic_xadd,atomic_xsub,TyDesc};
|
||||||
use ptr::null;
|
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());
|
assert!(td.is_not_null());
|
||||||
|
|
||||||
let total_size = get_box_size(size, (*td).align);
|
let total_size = get_box_size(size, (*td).align);
|
||||||
let p = c_malloc(total_size as size_t);
|
let p = c_malloc(total_size as size_t);
|
||||||
assert!(p.is_not_null());
|
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);
|
let box: &mut BoxRepr = transmute(p);
|
||||||
box.header.ref_count = -1; // Exchange values not ref counted
|
box.header.ref_count = -1; // Exchange values not ref counted
|
||||||
box.header.type_desc = td;
|
box.header.type_desc = td;
|
||||||
|
@ -17,23 +17,11 @@ use cast;
|
|||||||
use gc;
|
use gc;
|
||||||
use io;
|
use io;
|
||||||
use libc;
|
use libc;
|
||||||
use libc::{c_void, c_char, size_t};
|
use libc::{c_char, size_t};
|
||||||
use repr;
|
use repr;
|
||||||
use str;
|
use str;
|
||||||
use unstable::intrinsics;
|
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
|
/// The representation of a Rust closure
|
||||||
pub struct Closure {
|
pub struct Closure {
|
||||||
code: *(),
|
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
|
/// Returns the size of a type
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn size_of<T>() -> uint {
|
pub fn size_of<T>() -> uint {
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
// option. This file may not be copied, modified, or distributed
|
// option. This file may not be copied, modified, or distributed
|
||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
use sys::{TypeDesc, size_of};
|
use sys::size_of;
|
||||||
use libc::{c_void, size_t};
|
use libc::{c_void, size_t};
|
||||||
use c_malloc = libc::malloc;
|
use c_malloc = libc::malloc;
|
||||||
use c_free = libc::free;
|
use c_free = libc::free;
|
||||||
@ -16,18 +16,18 @@ use managed::raw::{BoxHeaderRepr, BoxRepr};
|
|||||||
use cast::transmute;
|
use cast::transmute;
|
||||||
use unstable::intrinsics::{atomic_xadd,atomic_xsub};
|
use unstable::intrinsics::{atomic_xadd,atomic_xsub};
|
||||||
use ptr::null;
|
use ptr::null;
|
||||||
|
#[cfg(stage0)]
|
||||||
use intrinsic::TyDesc;
|
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());
|
assert!(td.is_not_null());
|
||||||
|
|
||||||
let total_size = get_box_size(size, (*td).align);
|
let total_size = get_box_size(size, (*td).align);
|
||||||
let p = c_malloc(total_size as size_t);
|
let p = c_malloc(total_size as size_t);
|
||||||
assert!(p.is_not_null());
|
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);
|
let box: &mut BoxRepr = transmute(p);
|
||||||
box.header.ref_count = -1; // Exchange values not ref counted
|
box.header.ref_count = -1; // Exchange values not ref counted
|
||||||
box.header.type_desc = td;
|
box.header.type_desc = td;
|
||||||
|
@ -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"]
|
#[abi = "rust-intrinsic"]
|
||||||
pub extern "rust-intrinsic" {
|
pub extern "rust-intrinsic" {
|
||||||
|
|
||||||
@ -159,6 +283,9 @@ pub 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;
|
||||||
|
#[cfg(stage0)]
|
||||||
pub fn get_tydesc<T>() -> *();
|
pub fn get_tydesc<T>() -> *();
|
||||||
|
|
||||||
/// Create a value initialized to zero.
|
/// Create a value initialized to zero.
|
||||||
@ -181,9 +308,8 @@ pub extern "rust-intrinsic" {
|
|||||||
/// Returns `true` if a type requires drop glue.
|
/// Returns `true` if a type requires drop glue.
|
||||||
pub fn needs_drop<T>() -> bool;
|
pub fn needs_drop<T>() -> bool;
|
||||||
|
|
||||||
// XXX: intrinsic uses legacy modes and has reference to TyDesc
|
#[cfg(not(stage0))]
|
||||||
// and TyVisitor which are in librustc
|
pub fn visit_tydesc(td: *TyDesc, tv: @TyVisitor);
|
||||||
//fn visit_tydesc(++td: *TyDesc, &&tv: TyVisitor) -> ();
|
|
||||||
|
|
||||||
pub fn frame_address(f: &once fn(*u8));
|
pub fn frame_address(f: &once fn(*u8));
|
||||||
|
|
||||||
|
@ -30,6 +30,10 @@ 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};
|
||||||
use vec;
|
use vec;
|
||||||
use util;
|
use util;
|
||||||
|
|
||||||
@ -37,19 +41,22 @@ use util;
|
|||||||
|
|
||||||
pub mod rustrt {
|
pub mod rustrt {
|
||||||
use libc;
|
use libc;
|
||||||
use sys;
|
|
||||||
use vec::raw;
|
use vec::raw;
|
||||||
|
#[cfg(stage0)]
|
||||||
|
use intrinsic::{TyDesc};
|
||||||
|
#[cfg(not(stage0))]
|
||||||
|
use unstable::intrinsics::{TyDesc};
|
||||||
|
|
||||||
#[abi = "cdecl"]
|
#[abi = "cdecl"]
|
||||||
pub extern {
|
pub extern {
|
||||||
// These names are terrible. reserve_shared applies
|
// These names are terrible. reserve_shared applies
|
||||||
// to ~[] and reserve_shared_actual applies to @[].
|
// to ~[] and reserve_shared_actual applies to @[].
|
||||||
#[fast_ffi]
|
#[fast_ffi]
|
||||||
unsafe fn vec_reserve_shared(t: *sys::TypeDesc,
|
unsafe fn vec_reserve_shared(t: *TyDesc,
|
||||||
v: **raw::VecRepr,
|
v: **raw::VecRepr,
|
||||||
n: libc::size_t);
|
n: libc::size_t);
|
||||||
#[fast_ffi]
|
#[fast_ffi]
|
||||||
unsafe fn vec_reserve_shared_actual(t: *sys::TypeDesc,
|
unsafe fn vec_reserve_shared_actual(t: *TyDesc,
|
||||||
v: **raw::VecRepr,
|
v: **raw::VecRepr,
|
||||||
n: libc::size_t);
|
n: libc::size_t);
|
||||||
}
|
}
|
||||||
@ -78,7 +85,7 @@ pub fn reserve<T>(v: &mut ~[T], n: uint) {
|
|||||||
if capacity(v) < n {
|
if capacity(v) < n {
|
||||||
unsafe {
|
unsafe {
|
||||||
let ptr: **raw::VecRepr = cast::transmute(v);
|
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 ==
|
if ((**ptr).box_header.ref_count ==
|
||||||
managed::raw::RC_MANAGED_UNIQUE) {
|
managed::raw::RC_MANAGED_UNIQUE) {
|
||||||
rustrt::vec_reserve_shared_actual(td, ptr, n as libc::size_t);
|
rustrt::vec_reserve_shared_actual(td, ptr, n as libc::size_t);
|
||||||
|
@ -331,21 +331,18 @@ pub mod special_idents {
|
|||||||
pub static str : ident = ident { name: 19, ctxt: 0}; // for the type
|
pub static str : ident = ident { name: 19, ctxt: 0}; // for the type
|
||||||
|
|
||||||
/* outside of libsyntax */
|
/* outside of libsyntax */
|
||||||
pub static ty_visitor : ident = ident { name: 20, ctxt: 0};
|
pub static arg : ident = ident { name: 20, ctxt: 0};
|
||||||
pub static arg : ident = ident { name: 21, ctxt: 0};
|
pub static descrim : ident = ident { name: 21, ctxt: 0};
|
||||||
pub static descrim : ident = ident { name: 22, ctxt: 0};
|
pub static clownshoe_abi : ident = ident { name: 22, ctxt: 0};
|
||||||
pub static clownshoe_abi : ident = ident { name: 23, ctxt: 0};
|
pub static clownshoe_stack_shim : ident = ident { name: 23, ctxt: 0};
|
||||||
pub static clownshoe_stack_shim : ident = ident { name: 24, ctxt: 0};
|
pub static main : ident = ident { name: 24, ctxt: 0};
|
||||||
pub static tydesc : ident = ident { name: 25, ctxt: 0};
|
pub static opaque : ident = ident { name: 25, ctxt: 0};
|
||||||
pub static main : ident = ident { name: 26, ctxt: 0};
|
pub static blk : ident = ident { name: 26, ctxt: 0};
|
||||||
pub static opaque : ident = ident { name: 27, ctxt: 0};
|
pub static statik : ident = ident { name: 27, ctxt: 0};
|
||||||
pub static blk : ident = ident { name: 28, ctxt: 0};
|
pub static clownshoes_foreign_mod: ident = ident { name: 28, ctxt: 0};
|
||||||
pub static statik : ident = ident { name: 29, ctxt: 0};
|
pub static unnamed_field: ident = ident { name: 29, ctxt: 0};
|
||||||
pub static intrinsic : ident = ident { name: 30, ctxt: 0};
|
pub static c_abi: ident = ident { name: 30, ctxt: 0};
|
||||||
pub static clownshoes_foreign_mod: ident = ident { name: 31, ctxt: 0};
|
pub static type_self: ident = ident { name: 31, ctxt: 0}; // `Self`
|
||||||
pub static unnamed_field: ident = ident { name: 32, ctxt: 0};
|
|
||||||
pub static c_abi: ident = ident { name: 33, ctxt: 0};
|
|
||||||
pub static type_self: ident = ident { name: 34, ctxt: 0}; // `Self`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -426,59 +423,56 @@ fn mk_fresh_ident_interner() -> @ident_interner {
|
|||||||
"tt", // 17
|
"tt", // 17
|
||||||
"matchers", // 18
|
"matchers", // 18
|
||||||
"str", // 19
|
"str", // 19
|
||||||
"TyVisitor", // 20
|
"arg", // 20
|
||||||
"arg", // 21
|
"descrim", // 21
|
||||||
"descrim", // 22
|
"__rust_abi", // 22
|
||||||
"__rust_abi", // 23
|
"__rust_stack_shim", // 23
|
||||||
"__rust_stack_shim", // 24
|
"main", // 24
|
||||||
"TyDesc", // 25
|
"<opaque>", // 25
|
||||||
"main", // 26
|
"blk", // 26
|
||||||
"<opaque>", // 27
|
"static", // 27
|
||||||
"blk", // 28
|
"__foreign_mod__", // 28
|
||||||
"static", // 29
|
"__field__", // 29
|
||||||
"intrinsic", // 30
|
"C", // 30
|
||||||
"__foreign_mod__", // 31
|
"Self", // 31
|
||||||
"__field__", // 32
|
|
||||||
"C", // 33
|
|
||||||
"Self", // 34
|
|
||||||
|
|
||||||
"as", // 35
|
"as", // 32
|
||||||
"break", // 36
|
"break", // 33
|
||||||
"const", // 37
|
"const", // 34
|
||||||
"copy", // 38
|
"copy", // 35
|
||||||
"do", // 39
|
"do", // 36
|
||||||
"else", // 40
|
"else", // 37
|
||||||
"enum", // 41
|
"enum", // 38
|
||||||
"extern", // 42
|
"extern", // 39
|
||||||
"false", // 43
|
"false", // 40
|
||||||
"fn", // 44
|
"fn", // 41
|
||||||
"for", // 45
|
"for", // 42
|
||||||
"if", // 46
|
"if", // 43
|
||||||
"impl", // 47
|
"impl", // 44
|
||||||
"let", // 48
|
"let", // 45
|
||||||
"__log", // 49
|
"__log", // 46
|
||||||
"loop", // 50
|
"loop", // 47
|
||||||
"match", // 51
|
"match", // 48
|
||||||
"mod", // 52
|
"mod", // 49
|
||||||
"mut", // 53
|
"mut", // 50
|
||||||
"once", // 54
|
"once", // 51
|
||||||
"priv", // 55
|
"priv", // 52
|
||||||
"pub", // 56
|
"pub", // 53
|
||||||
"pure", // 57
|
"pure", // 54
|
||||||
"ref", // 58
|
"ref", // 55
|
||||||
"return", // 59
|
"return", // 56
|
||||||
"static", // 29 -- also a special ident
|
"static", // 27 -- also a special ident
|
||||||
"self", // 8 -- also a special ident
|
"self", // 8 -- also a special ident
|
||||||
"struct", // 60
|
"struct", // 57
|
||||||
"super", // 61
|
"super", // 58
|
||||||
"true", // 62
|
"true", // 59
|
||||||
"trait", // 63
|
"trait", // 60
|
||||||
"type", // 64
|
"type", // 61
|
||||||
"unsafe", // 65
|
"unsafe", // 62
|
||||||
"use", // 66
|
"use", // 63
|
||||||
"while", // 67
|
"while", // 64
|
||||||
|
|
||||||
"be", // 68
|
"be", // 65
|
||||||
];
|
];
|
||||||
|
|
||||||
@ident_interner {
|
@ident_interner {
|
||||||
@ -612,42 +606,42 @@ pub mod keywords {
|
|||||||
impl Keyword {
|
impl Keyword {
|
||||||
pub fn to_ident(&self) -> ident {
|
pub fn to_ident(&self) -> ident {
|
||||||
match *self {
|
match *self {
|
||||||
As => ident { name: 35, ctxt: 0 },
|
As => ident { name: 32, ctxt: 0 },
|
||||||
Break => ident { name: 36, ctxt: 0 },
|
Break => ident { name: 33, ctxt: 0 },
|
||||||
Const => ident { name: 37, ctxt: 0 },
|
Const => ident { name: 34, ctxt: 0 },
|
||||||
Copy => ident { name: 38, ctxt: 0 },
|
Copy => ident { name: 35, ctxt: 0 },
|
||||||
Do => ident { name: 39, ctxt: 0 },
|
Do => ident { name: 36, ctxt: 0 },
|
||||||
Else => ident { name: 40, ctxt: 0 },
|
Else => ident { name: 37, ctxt: 0 },
|
||||||
Enum => ident { name: 41, ctxt: 0 },
|
Enum => ident { name: 38, ctxt: 0 },
|
||||||
Extern => ident { name: 42, ctxt: 0 },
|
Extern => ident { name: 39, ctxt: 0 },
|
||||||
False => ident { name: 43, ctxt: 0 },
|
False => ident { name: 40, ctxt: 0 },
|
||||||
Fn => ident { name: 44, ctxt: 0 },
|
Fn => ident { name: 41, ctxt: 0 },
|
||||||
For => ident { name: 45, ctxt: 0 },
|
For => ident { name: 42, ctxt: 0 },
|
||||||
If => ident { name: 46, ctxt: 0 },
|
If => ident { name: 43, ctxt: 0 },
|
||||||
Impl => ident { name: 47, ctxt: 0 },
|
Impl => ident { name: 44, ctxt: 0 },
|
||||||
Let => ident { name: 48, ctxt: 0 },
|
Let => ident { name: 45, ctxt: 0 },
|
||||||
__Log => ident { name: 49, ctxt: 0 },
|
__Log => ident { name: 46, ctxt: 0 },
|
||||||
Loop => ident { name: 50, ctxt: 0 },
|
Loop => ident { name: 47, ctxt: 0 },
|
||||||
Match => ident { name: 51, ctxt: 0 },
|
Match => ident { name: 48, ctxt: 0 },
|
||||||
Mod => ident { name: 52, ctxt: 0 },
|
Mod => ident { name: 49, ctxt: 0 },
|
||||||
Mut => ident { name: 53, ctxt: 0 },
|
Mut => ident { name: 50, ctxt: 0 },
|
||||||
Once => ident { name: 54, ctxt: 0 },
|
Once => ident { name: 51, ctxt: 0 },
|
||||||
Priv => ident { name: 55, ctxt: 0 },
|
Priv => ident { name: 52, ctxt: 0 },
|
||||||
Pub => ident { name: 56, ctxt: 0 },
|
Pub => ident { name: 53, ctxt: 0 },
|
||||||
Pure => ident { name: 57, ctxt: 0 },
|
Pure => ident { name: 54, ctxt: 0 },
|
||||||
Ref => ident { name: 58, ctxt: 0 },
|
Ref => ident { name: 55, ctxt: 0 },
|
||||||
Return => ident { name: 59, ctxt: 0 },
|
Return => ident { name: 56, ctxt: 0 },
|
||||||
Static => ident { name: 29, ctxt: 0 },
|
Static => ident { name: 27, ctxt: 0 },
|
||||||
Self => ident { name: 8, ctxt: 0 },
|
Self => ident { name: 8, ctxt: 0 },
|
||||||
Struct => ident { name: 60, ctxt: 0 },
|
Struct => ident { name: 57, ctxt: 0 },
|
||||||
Super => ident { name: 61, ctxt: 0 },
|
Super => ident { name: 58, ctxt: 0 },
|
||||||
True => ident { name: 62, ctxt: 0 },
|
True => ident { name: 59, ctxt: 0 },
|
||||||
Trait => ident { name: 63, ctxt: 0 },
|
Trait => ident { name: 60, ctxt: 0 },
|
||||||
Type => ident { name: 64, ctxt: 0 },
|
Type => ident { name: 61, ctxt: 0 },
|
||||||
Unsafe => ident { name: 65, ctxt: 0 },
|
Unsafe => ident { name: 62, ctxt: 0 },
|
||||||
Use => ident { name: 66, ctxt: 0 },
|
Use => ident { name: 63, ctxt: 0 },
|
||||||
While => ident { name: 67, ctxt: 0 },
|
While => ident { name: 64, ctxt: 0 },
|
||||||
Be => ident { name: 68, ctxt: 0 },
|
Be => ident { name: 65, ctxt: 0 },
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -663,7 +657,7 @@ pub fn is_keyword(kw: keywords::Keyword, tok: &Token) -> bool {
|
|||||||
pub fn is_any_keyword(tok: &Token) -> bool {
|
pub fn is_any_keyword(tok: &Token) -> bool {
|
||||||
match *tok {
|
match *tok {
|
||||||
token::IDENT(sid, false) => match sid.name {
|
token::IDENT(sid, false) => match sid.name {
|
||||||
8 | 29 | 35 .. 68 => true,
|
8 | 27 | 32 .. 65 => true,
|
||||||
_ => false,
|
_ => false,
|
||||||
},
|
},
|
||||||
_ => false
|
_ => false
|
||||||
@ -673,7 +667,7 @@ pub fn is_any_keyword(tok: &Token) -> bool {
|
|||||||
pub fn is_strict_keyword(tok: &Token) -> bool {
|
pub fn is_strict_keyword(tok: &Token) -> bool {
|
||||||
match *tok {
|
match *tok {
|
||||||
token::IDENT(sid, false) => match sid.name {
|
token::IDENT(sid, false) => match sid.name {
|
||||||
8 | 29 | 35 .. 67 => true,
|
8 | 27 | 32 .. 64 => true,
|
||||||
_ => false,
|
_ => false,
|
||||||
},
|
},
|
||||||
_ => false,
|
_ => false,
|
||||||
@ -683,7 +677,7 @@ pub fn is_strict_keyword(tok: &Token) -> bool {
|
|||||||
pub fn is_reserved_keyword(tok: &Token) -> bool {
|
pub fn is_reserved_keyword(tok: &Token) -> bool {
|
||||||
match *tok {
|
match *tok {
|
||||||
token::IDENT(sid, false) => match sid.name {
|
token::IDENT(sid, false) => match sid.name {
|
||||||
68 => true,
|
65 => true,
|
||||||
_ => false,
|
_ => false,
|
||||||
},
|
},
|
||||||
_ => false,
|
_ => false,
|
||||||
|
@ -739,15 +739,6 @@ rust_task_deref(rust_task *task) {
|
|||||||
task->deref();
|
task->deref();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Must call on rust stack.
|
|
||||||
extern "C" CDECL void
|
|
||||||
rust_call_tydesc_glue(void *root, size_t *tydesc, size_t glue_index) {
|
|
||||||
void (*glue_fn)(void *, void *, void *) =
|
|
||||||
(void (*)(void *, void *, void *))tydesc[glue_index];
|
|
||||||
if (glue_fn)
|
|
||||||
glue_fn(0, 0, root);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Don't run on the Rust stack!
|
// Don't run on the Rust stack!
|
||||||
extern "C" void
|
extern "C" void
|
||||||
rust_log_str(uint32_t level, const char *str, size_t size) {
|
rust_log_str(uint32_t level, const char *str, size_t size) {
|
||||||
|
@ -183,7 +183,11 @@ void task_start_wrapper(spawn_args *a)
|
|||||||
if(env) {
|
if(env) {
|
||||||
// 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, NULL, box_body(env));
|
td->drop_glue(NULL,
|
||||||
|
#ifdef _RUST_STAGE0
|
||||||
|
NULL,
|
||||||
|
#endif
|
||||||
|
box_body(env));
|
||||||
task->kernel->region()->free(env);
|
task->kernel->region()->free(env);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,7 +25,11 @@ typedef void (*CDECL spawn_fn)(rust_opaque_box*, void *);
|
|||||||
|
|
||||||
struct type_desc;
|
struct type_desc;
|
||||||
|
|
||||||
typedef void CDECL (glue_fn)(void *, const type_desc **, void *);
|
typedef void CDECL (glue_fn)(void *,
|
||||||
|
#ifdef _RUST_STAGE0
|
||||||
|
const type_desc **,
|
||||||
|
#endif
|
||||||
|
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
|
||||||
// header; you can obtain a ptr via box_body() below.
|
// header; you can obtain a ptr via box_body() below.
|
||||||
@ -57,8 +61,6 @@ struct type_desc {
|
|||||||
glue_fn *drop_glue;
|
glue_fn *drop_glue;
|
||||||
glue_fn *free_glue;
|
glue_fn *free_glue;
|
||||||
glue_fn *visit_glue;
|
glue_fn *visit_glue;
|
||||||
const uint8_t *unused;
|
|
||||||
const uint8_t *unused2;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
extern "C" type_desc *rust_clone_type_desc(type_desc*);
|
extern "C" type_desc *rust_clone_type_desc(type_desc*);
|
||||||
|
@ -21,8 +21,6 @@ struct type_desc str_body_tydesc = {
|
|||||||
NULL, // drop_glue
|
NULL, // drop_glue
|
||||||
NULL, // free_glue
|
NULL, // free_glue
|
||||||
NULL, // visit_glue
|
NULL, // visit_glue
|
||||||
NULL, // shape
|
|
||||||
NULL, // shape_tables
|
|
||||||
};
|
};
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -176,7 +176,6 @@ rust_set_task_local_data
|
|||||||
rust_task_local_data_atexit
|
rust_task_local_data_atexit
|
||||||
rust_task_ref
|
rust_task_ref
|
||||||
rust_task_deref
|
rust_task_deref
|
||||||
rust_call_tydesc_glue
|
|
||||||
tdefl_compress_mem_to_heap
|
tdefl_compress_mem_to_heap
|
||||||
tinfl_decompress_mem_to_heap
|
tinfl_decompress_mem_to_heap
|
||||||
rust_gc_metadata
|
rust_gc_metadata
|
||||||
|
@ -1,11 +1,5 @@
|
|||||||
use std::libc;
|
|
||||||
use std::sys;
|
|
||||||
use std::vec;
|
|
||||||
|
|
||||||
extern {
|
extern {
|
||||||
pub unsafe fn vec_reserve_shared_actual(t: *sys::TypeDesc,
|
pub unsafe fn free(p: *u8);
|
||||||
v: **vec::raw::VecRepr,
|
|
||||||
n: libc::size_t);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn main() {
|
pub fn main() {
|
||||||
|
@ -10,15 +10,14 @@
|
|||||||
|
|
||||||
// xfail-fast
|
// xfail-fast
|
||||||
|
|
||||||
use std::bool;
|
|
||||||
use std::int;
|
use std::int;
|
||||||
use std::libc::c_void;
|
use std::libc::c_void;
|
||||||
use std::ptr;
|
use std::ptr;
|
||||||
use std::sys;
|
use std::sys;
|
||||||
use std::vec::UnboxedVecRepr;
|
use std::vec::UnboxedVecRepr;
|
||||||
use intrinsic::{TyDesc, get_tydesc, visit_tydesc, TyVisitor, Opaque};
|
use std::unstable::intrinsics::{TyDesc, get_tydesc, visit_tydesc, TyVisitor, Opaque};
|
||||||
|
|
||||||
#[doc = "High-level interfaces to `intrinsic::visit_ty` reflection system."]
|
#[doc = "High-level interfaces to `std::unstable::intrinsics::visit_ty` reflection system."]
|
||||||
|
|
||||||
/// Trait for visitor that wishes to reflect on data.
|
/// Trait for visitor that wishes to reflect on data.
|
||||||
trait movable_ptr {
|
trait movable_ptr {
|
||||||
@ -637,7 +636,9 @@ impl TyVisitor for my_visitor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn get_tydesc_for<T>(_t: T) -> *TyDesc {
|
fn get_tydesc_for<T>(_t: T) -> *TyDesc {
|
||||||
get_tydesc::<T>()
|
unsafe {
|
||||||
|
get_tydesc::<T>()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Triple { x: int, y: int, z: int }
|
struct Triple { x: int, y: int, z: int }
|
||||||
@ -651,8 +652,8 @@ pub fn main() {
|
|||||||
vals: ~[]});
|
vals: ~[]});
|
||||||
let v = ptr_visit_adaptor(Inner {inner: u});
|
let v = ptr_visit_adaptor(Inner {inner: u});
|
||||||
let td = get_tydesc_for(r);
|
let td = get_tydesc_for(r);
|
||||||
unsafe { error!("tydesc sz: %u, align: %u",
|
error!("tydesc sz: %u, align: %u",
|
||||||
(*td).size, (*td).align); }
|
(*td).size, (*td).align);
|
||||||
let v = @v as @TyVisitor;
|
let v = @v as @TyVisitor;
|
||||||
visit_tydesc(td, v);
|
visit_tydesc(td, v);
|
||||||
|
|
||||||
@ -661,8 +662,7 @@ pub fn main() {
|
|||||||
println(fmt!("val: %s", *s));
|
println(fmt!("val: %s", *s));
|
||||||
}
|
}
|
||||||
error!("%?", u.vals.clone());
|
error!("%?", u.vals.clone());
|
||||||
assert!(u.vals == ~[
|
assert_eq!(u.vals.clone(),
|
||||||
~"1", ~"2", ~"3", ~"true", ~"false", ~"5", ~"4", ~"3", ~"12"
|
~[ ~"1", ~"2", ~"3", ~"true", ~"false", ~"5", ~"4", ~"3", ~"12"]);
|
||||||
]);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,141 +8,153 @@
|
|||||||
// option. This file may not be copied, modified, or distributed
|
// option. This file may not be copied, modified, or distributed
|
||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
// xfail-test
|
use std::unstable::intrinsics::{TyDesc, get_tydesc, visit_tydesc, TyVisitor, Opaque};
|
||||||
use intrinsic::{TyDesc, get_tydesc, visit_tydesc, TyVisitor};
|
|
||||||
struct my_visitor(@mut { types: ~[str] });
|
|
||||||
|
|
||||||
impl TyVisitor for my_visitor {
|
struct MyVisitor {
|
||||||
fn visit_bot() -> bool {
|
types: @mut ~[~str],
|
||||||
self.types += ~["bot"];
|
}
|
||||||
|
|
||||||
|
impl TyVisitor for MyVisitor {
|
||||||
|
fn visit_bot(&self) -> bool {
|
||||||
|
self.types.push(~"bot");
|
||||||
error!("visited bot type");
|
error!("visited bot type");
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
fn visit_nil() -> bool {
|
fn visit_nil(&self) -> bool {
|
||||||
self.types += ~["nil"];
|
self.types.push(~"nil");
|
||||||
error!("visited nil type");
|
error!("visited nil type");
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
fn visit_bool() -> bool {
|
fn visit_bool(&self) -> bool {
|
||||||
self.types += ~["bool"];
|
self.types.push(~"bool");
|
||||||
error!("visited bool type");
|
error!("visited bool type");
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
fn visit_int() -> bool {
|
fn visit_int(&self) -> bool {
|
||||||
self.types += ~["int"];
|
self.types.push(~"int");
|
||||||
error!("visited int type");
|
error!("visited int type");
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
fn visit_i8() -> bool {
|
fn visit_i8(&self) -> bool {
|
||||||
self.types += ~["i8"];
|
self.types.push(~"i8");
|
||||||
error!("visited i8 type");
|
error!("visited i8 type");
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
fn visit_i16() -> bool {
|
fn visit_i16(&self) -> bool {
|
||||||
self.types += ~["i16"];
|
self.types.push(~"i16");
|
||||||
error!("visited i16 type");
|
error!("visited i16 type");
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
fn visit_i32() -> bool { true }
|
fn visit_i32(&self) -> bool { true }
|
||||||
fn visit_i64() -> bool { true }
|
fn visit_i64(&self) -> bool { true }
|
||||||
|
|
||||||
fn visit_uint() -> bool { true }
|
fn visit_uint(&self) -> bool { true }
|
||||||
fn visit_u8() -> bool { true }
|
fn visit_u8(&self) -> bool { true }
|
||||||
fn visit_u16() -> bool { true }
|
fn visit_u16(&self) -> bool { true }
|
||||||
fn visit_u32() -> bool { true }
|
fn visit_u32(&self) -> bool { true }
|
||||||
fn visit_u64() -> bool { true }
|
fn visit_u64(&self) -> bool { true }
|
||||||
|
|
||||||
fn visit_float() -> bool { true }
|
fn visit_float(&self) -> bool { true }
|
||||||
fn visit_f32() -> bool { true }
|
fn visit_f32(&self) -> bool { true }
|
||||||
fn visit_f64() -> bool { true }
|
fn visit_f64(&self) -> bool { true }
|
||||||
|
|
||||||
fn visit_char() -> bool { true }
|
fn visit_char(&self) -> bool { true }
|
||||||
fn visit_str() -> bool { true }
|
fn visit_str(&self) -> bool { true }
|
||||||
|
|
||||||
fn visit_estr_box() -> bool { true }
|
fn visit_estr_box(&self) -> bool { true }
|
||||||
fn visit_estr_uniq() -> bool { true }
|
fn visit_estr_uniq(&self) -> bool { true }
|
||||||
fn visit_estr_slice() -> bool { true }
|
fn visit_estr_slice(&self) -> bool { true }
|
||||||
fn visit_estr_fixed(_sz: uint, _sz: uint,
|
fn visit_estr_fixed(&self,
|
||||||
|
_sz: uint, _sz: uint,
|
||||||
_align: uint) -> bool { true }
|
_align: uint) -> bool { true }
|
||||||
|
|
||||||
fn visit_box(_mtbl: uint, _inner: *TyDesc) -> bool { true }
|
fn visit_box(&self, _mtbl: uint, _inner: *TyDesc) -> bool { true }
|
||||||
fn visit_uniq(_mtbl: uint, _inner: *TyDesc) -> bool { true }
|
fn visit_uniq(&self, _mtbl: uint, _inner: *TyDesc) -> bool { true }
|
||||||
fn visit_ptr(_mtbl: uint, _inner: *TyDesc) -> bool { true }
|
fn visit_ptr(&self, _mtbl: uint, _inner: *TyDesc) -> bool { true }
|
||||||
fn visit_rptr(_mtbl: uint, _inner: *TyDesc) -> bool { true }
|
fn visit_rptr(&self, _mtbl: uint, _inner: *TyDesc) -> bool { true }
|
||||||
|
|
||||||
fn visit_vec(_mtbl: uint, inner: *TyDesc) -> bool {
|
fn visit_vec(&self, _mtbl: uint, _inner: *TyDesc) -> bool { true }
|
||||||
self.types += ~["["];
|
fn visit_unboxed_vec(&self, _mtbl: uint, _inner: *TyDesc) -> bool { true }
|
||||||
visit_tydesc(inner, my_visitor(*self) as TyVisitor);
|
fn visit_evec_box(&self, _mtbl: uint, _inner: *TyDesc) -> bool { true }
|
||||||
self.types += ~["]"];
|
fn visit_evec_uniq(&self, _mtbl: uint, inner: *TyDesc) -> bool {
|
||||||
|
self.types.push(~"[");
|
||||||
|
unsafe {
|
||||||
|
visit_tydesc(inner, (@*self) as @TyVisitor);
|
||||||
|
}
|
||||||
|
self.types.push(~"]");
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
fn visit_unboxed_vec(_mtbl: uint, _inner: *TyDesc) -> bool { true }
|
fn visit_evec_slice(&self, _mtbl: uint, _inner: *TyDesc) -> bool { true }
|
||||||
fn visit_evec_box(_mtbl: uint, _inner: *TyDesc) -> bool { true }
|
fn visit_evec_fixed(&self, _n: uint, _sz: uint, _align: uint,
|
||||||
fn visit_evec_uniq(_mtbl: uint, _inner: *TyDesc) -> bool { true }
|
|
||||||
fn visit_evec_slice(_mtbl: uint, _inner: *TyDesc) -> bool { true }
|
|
||||||
fn visit_evec_fixed(_n: uint, _sz: uint, _align: uint,
|
|
||||||
_mtbl: uint, _inner: *TyDesc) -> bool { true }
|
_mtbl: uint, _inner: *TyDesc) -> bool { true }
|
||||||
|
|
||||||
fn visit_enter_rec(_n_fields: uint,
|
fn visit_enter_rec(&self, _n_fields: uint,
|
||||||
_sz: uint, _align: uint) -> bool { true }
|
_sz: uint, _align: uint) -> bool { true }
|
||||||
fn visit_rec_field(_i: uint, _name: &str,
|
fn visit_rec_field(&self, _i: uint, _name: &str,
|
||||||
_mtbl: uint, _inner: *TyDesc) -> bool { true }
|
_mtbl: uint, _inner: *TyDesc) -> bool { true }
|
||||||
fn visit_leave_rec(_n_fields: uint,
|
fn visit_leave_rec(&self, _n_fields: uint,
|
||||||
_sz: uint, _align: uint) -> bool { true }
|
_sz: uint, _align: uint) -> bool { true }
|
||||||
|
|
||||||
fn visit_enter_class(_n_fields: uint,
|
fn visit_enter_class(&self, _n_fields: uint,
|
||||||
_sz: uint, _align: uint) -> bool { true }
|
_sz: uint, _align: uint) -> bool { true }
|
||||||
fn visit_class_field(_i: uint, _name: &str,
|
fn visit_class_field(&self, _i: uint, _name: &str,
|
||||||
_mtbl: uint, _inner: *TyDesc) -> bool { true }
|
_mtbl: uint, _inner: *TyDesc) -> bool { true }
|
||||||
fn visit_leave_class(_n_fields: uint,
|
fn visit_leave_class(&self, _n_fields: uint,
|
||||||
_sz: uint, _align: uint) -> bool { true }
|
_sz: uint, _align: uint) -> bool { true }
|
||||||
|
|
||||||
fn visit_enter_tup(_n_fields: uint,
|
fn visit_enter_tup(&self, _n_fields: uint,
|
||||||
_sz: uint, _align: uint) -> bool { true }
|
_sz: uint, _align: uint) -> bool { true }
|
||||||
fn visit_tup_field(_i: uint, _inner: *TyDesc) -> bool { true }
|
fn visit_tup_field(&self, _i: uint, _inner: *TyDesc) -> bool { true }
|
||||||
fn visit_leave_tup(_n_fields: uint,
|
fn visit_leave_tup(&self, _n_fields: uint,
|
||||||
_sz: uint, _align: uint) -> bool { true }
|
_sz: uint, _align: uint) -> bool { true }
|
||||||
|
|
||||||
fn visit_enter_enum(_n_variants: uint,
|
fn visit_enter_enum(&self, _n_variants: uint,
|
||||||
|
_get_disr: extern unsafe fn(ptr: *Opaque) -> int,
|
||||||
_sz: uint, _align: uint) -> bool { true }
|
_sz: uint, _align: uint) -> bool { true }
|
||||||
fn visit_enter_enum_variant(_variant: uint,
|
fn visit_enter_enum_variant(&self,
|
||||||
|
_variant: uint,
|
||||||
_disr_val: int,
|
_disr_val: int,
|
||||||
_n_fields: uint,
|
_n_fields: uint,
|
||||||
_name: &str) -> bool { true }
|
_name: &str) -> bool { true }
|
||||||
fn visit_enum_variant_field(_i: uint, _inner: *TyDesc) -> bool { true }
|
fn visit_enum_variant_field(&self, _i: uint, _offset: uint, _inner: *TyDesc) -> bool { true }
|
||||||
fn visit_leave_enum_variant(_variant: uint,
|
fn visit_leave_enum_variant(&self,
|
||||||
|
_variant: uint,
|
||||||
_disr_val: int,
|
_disr_val: int,
|
||||||
_n_fields: uint,
|
_n_fields: uint,
|
||||||
_name: &str) -> bool { true }
|
_name: &str) -> bool { true }
|
||||||
fn visit_leave_enum(_n_variants: uint,
|
fn visit_leave_enum(&self,
|
||||||
|
_n_variants: uint,
|
||||||
|
_get_disr: extern unsafe fn(ptr: *Opaque) -> int,
|
||||||
_sz: uint, _align: uint) -> bool { true }
|
_sz: uint, _align: uint) -> bool { true }
|
||||||
|
|
||||||
fn visit_enter_fn(_purity: uint, _proto: uint,
|
fn visit_enter_fn(&self, _purity: uint, _proto: uint,
|
||||||
_n_inputs: uint, _retstyle: uint) -> bool { true }
|
_n_inputs: uint, _retstyle: uint) -> bool { true }
|
||||||
fn visit_fn_input(_i: uint, _mode: uint, _inner: *TyDesc) -> bool { true }
|
fn visit_fn_input(&self, _i: uint, _mode: uint, _inner: *TyDesc) -> bool { true }
|
||||||
fn visit_fn_output(_retstyle: uint, _inner: *TyDesc) -> bool { true }
|
fn visit_fn_output(&self, _retstyle: uint, _inner: *TyDesc) -> bool { true }
|
||||||
fn visit_leave_fn(_purity: uint, _proto: uint,
|
fn visit_leave_fn(&self, _purity: uint, _proto: uint,
|
||||||
_n_inputs: uint, _retstyle: uint) -> bool { true }
|
_n_inputs: uint, _retstyle: uint) -> bool { true }
|
||||||
|
|
||||||
|
|
||||||
fn visit_trait() -> bool { true }
|
fn visit_trait(&self) -> bool { true }
|
||||||
fn visit_var() -> bool { true }
|
fn visit_var(&self) -> bool { true }
|
||||||
fn visit_var_integral() -> bool { true }
|
fn visit_var_integral(&self) -> bool { true }
|
||||||
fn visit_param(_i: uint) -> bool { true }
|
fn visit_param(&self, _i: uint) -> bool { true }
|
||||||
fn visit_self() -> bool { true }
|
fn visit_self(&self) -> bool { true }
|
||||||
fn visit_type() -> bool { true }
|
fn visit_type(&self) -> bool { true }
|
||||||
fn visit_opaque_box() -> bool { true }
|
fn visit_opaque_box(&self) -> bool { true }
|
||||||
fn visit_constr(_inner: *TyDesc) -> bool { true }
|
fn visit_constr(&self, _inner: *TyDesc) -> bool { true }
|
||||||
fn visit_closure_ptr(_ck: uint) -> bool { true }
|
fn visit_closure_ptr(&self, _ck: uint) -> bool { true }
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_ty<T>(v: TyVisitor) {
|
fn visit_ty<T>(v: @TyVisitor) {
|
||||||
visit_tydesc(get_tydesc::<T>(), v);
|
unsafe {
|
||||||
|
visit_tydesc(get_tydesc::<T>(), v);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn main() {
|
pub fn main() {
|
||||||
let v = my_visitor(@mut {types: ~[]});
|
let v = @MyVisitor {types: @mut ~[]};
|
||||||
let vv = v as TyVisitor;
|
let vv = v as @TyVisitor;
|
||||||
|
|
||||||
visit_ty::<bool>(vv);
|
visit_ty::<bool>(vv);
|
||||||
visit_ty::<int>(vv);
|
visit_ty::<int>(vv);
|
||||||
@ -150,9 +162,8 @@ pub fn main() {
|
|||||||
visit_ty::<i16>(vv);
|
visit_ty::<i16>(vv);
|
||||||
visit_ty::<~[int]>(vv);
|
visit_ty::<~[int]>(vv);
|
||||||
|
|
||||||
for (v.types.clone()).each {|s|
|
for v.types.iter().advance |&s| {
|
||||||
io::println(fmt!("type: %s", s));
|
println(fmt!("type: %s", s));
|
||||||
}
|
}
|
||||||
assert!(v.types == ["bool", "int", "i8", "i16",
|
assert_eq!((*v.types).clone(), ~[~"bool", ~"int", ~"i8", ~"i16", ~"[", ~"int", ~"]"]);
|
||||||
"[", "int", "]"]);
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user