diff --git a/src/libextra/arena.rs b/src/libextra/arena.rs index db4cf564babc5..cec3a2c1e952c 100644 --- a/src/libextra/arena.rs +++ b/src/libextra/arena.rs @@ -41,30 +41,21 @@ use list::{MutList, MutCons, MutNil}; use core::at_vec; use core::cast::{transmute, transmute_mut_region}; use core::cast; -use core::libc::size_t; use core::ptr; -use core::sys::TypeDesc; use core::sys; use core::uint; use core::vec; use core::unstable::intrinsics; +use core::unstable::intrinsics::{TyDesc}; -pub mod rustrt { - use core::libc::size_t; - use core::sys::TypeDesc; +#[cfg(not(stage0))] +use core::unstable::intrinsics::{get_tydesc}; - pub extern { - #[rust_stack] - unsafe fn rust_call_tydesc_glue(root: *u8, - tydesc: *TypeDesc, - field: size_t); - } +#[cfg(stage0)] +unsafe fn get_tydesc() -> *TyDesc { + intrinsics::get_tydesc::() as *TyDesc } -// 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 // allocated, and have capacities reserved, but the fill for the array // will always stay at 0. @@ -124,6 +115,19 @@ fn round_up_to(base: uint, align: uint) -> uint { (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 // in it. unsafe fn destroy_chunk(chunk: &Chunk) { @@ -136,19 +140,18 @@ unsafe fn destroy_chunk(chunk: &Chunk) { let (tydesc, is_done) = un_bitpack_tydesc_ptr(*tydesc_data); 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); //debug!("freeing object: idx = %u, size = %u, align = %u, done = %b", // start, size, align, is_done); if is_done { - rustrt::rust_call_tydesc_glue( - ptr::offset(buf, start), tydesc, tydesc_drop_glue_index); + call_drop_glue(tydesc, ptr::offset(buf, start) as *i8); } // 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>()); } } @@ -157,12 +160,12 @@ unsafe fn destroy_chunk(chunk: &Chunk) { // is necessary in order to properly do cleanup if a failure occurs // during an initializer. #[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); p_bits | (is_done as uint) } #[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) } @@ -202,7 +205,7 @@ impl Arena { #[inline] fn alloc_pod<'a, T>(&'a mut self, op: &fn() -> T) -> &'a T { unsafe { - let tydesc = sys::get_type_desc::(); + let tydesc = get_tydesc::(); let ptr = self.alloc_pod_inner((*tydesc).size, (*tydesc).align); let ptr: *mut T = transmute(ptr); intrinsics::move_val_init(&mut (*ptr), op()); @@ -230,13 +233,13 @@ impl Arena { let head = transmute_mut_region(&mut self.head); 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 end = start + n_bytes; if end > at_vec::capacity(head.data) { 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", // start, n_bytes, align, head.fill); @@ -249,7 +252,7 @@ impl Arena { #[inline] fn alloc_nonpod<'a, T>(&'a mut self, op: &fn() -> T) -> &'a T { unsafe { - let tydesc = sys::get_type_desc::(); + let tydesc = get_tydesc::(); let (ty_ptr, ptr) = self.alloc_nonpod_inner((*tydesc).size, (*tydesc).align); let ty_ptr: *mut uint = transmute(ty_ptr); diff --git a/src/libextra/dbg.rs b/src/libextra/dbg.rs index cbd7cb5e3c08f..43c4aecdd27fa 100644 --- a/src/libextra/dbg.rs +++ b/src/libextra/dbg.rs @@ -13,56 +13,62 @@ #[allow(missing_doc)]; 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 { - use core::sys; + #[cfg(stage0)] + use intrinsic::{TyDesc}; + #[cfg(not(stage0))] + use core::unstable::intrinsics::{TyDesc}; #[abi = "cdecl"] pub extern { - pub unsafe fn debug_tydesc(td: *sys::TypeDesc); - pub unsafe fn debug_opaque(td: *sys::TypeDesc, x: *()); - pub unsafe fn debug_box(td: *sys::TypeDesc, x: *()); - pub unsafe fn debug_tag(td: *sys::TypeDesc, x: *()); - pub unsafe fn debug_fn(td: *sys::TypeDesc, x: *()); - pub unsafe fn debug_ptrcast(td: *sys::TypeDesc, x: *()) -> *(); + pub unsafe fn debug_tydesc(td: *TyDesc); + pub unsafe fn debug_opaque(td: *TyDesc, x: *()); + pub unsafe fn debug_box(td: *TyDesc, x: *()); + pub unsafe fn debug_tag(td: *TyDesc, x: *()); + pub unsafe fn debug_fn(td: *TyDesc, x: *()); + pub unsafe fn debug_ptrcast(td: *TyDesc, x: *()) -> *(); pub unsafe fn rust_dbg_breakpoint(); } } pub fn debug_tydesc() { unsafe { - rustrt::debug_tydesc(sys::get_type_desc::()); + rustrt::debug_tydesc(get_tydesc::()); } } pub fn debug_opaque(x: T) { unsafe { - rustrt::debug_opaque(sys::get_type_desc::(), transmute(&x)); + rustrt::debug_opaque(get_tydesc::(), transmute(&x)); } } pub fn debug_box(x: @T) { unsafe { - rustrt::debug_box(sys::get_type_desc::(), transmute(&x)); + rustrt::debug_box(get_tydesc::(), transmute(&x)); } } pub fn debug_tag(x: T) { unsafe { - rustrt::debug_tag(sys::get_type_desc::(), transmute(&x)); + rustrt::debug_tag(get_tydesc::(), transmute(&x)); } } pub fn debug_fn(x: T) { unsafe { - rustrt::debug_fn(sys::get_type_desc::(), transmute(&x)); + rustrt::debug_fn(get_tydesc::(), transmute(&x)); } } pub unsafe fn ptr_cast(x: @T) -> @U { transmute( - rustrt::debug_ptrcast(sys::get_type_desc::(), transmute(x))) + rustrt::debug_ptrcast(get_tydesc::(), transmute(x))) } /// Triggers a debugger breakpoint diff --git a/src/librustc/back/abi.rs b/src/librustc/back/abi.rs index 004170dea7fe6..05b6e90c682f0 100644 --- a/src/librustc/back/abi.rs +++ b/src/librustc/back/abi.rs @@ -8,9 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. - - - pub static rc_base_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_free_glue: uint = 4u; pub static tydesc_field_visit_glue: uint = 5u; -pub static tydesc_field_shape: uint = 6u; -pub static tydesc_field_shape_tables: uint = 7u; -pub static n_tydesc_fields: uint = 8u; +pub static n_tydesc_fields: uint = 6u; // The two halves of a closure: code and environment. 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_len: uint = 1u; -pub static worst_case_glue_call_args: uint = 7u; - 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"; } diff --git a/src/librustc/driver/driver.rs b/src/librustc/driver/driver.rs index 1a7041c08840e..fbb273450df29 100644 --- a/src/librustc/driver/driver.rs +++ b/src/librustc/driver/driver.rs @@ -206,9 +206,6 @@ pub fn compile_rest(sess: Session, let mut crate = crate_opt.unwrap(); let (llcx, llmod, link_meta) = { - crate = time(time_passes, ~"intrinsic injection", || - front::intrinsic_inject::inject_intrinsic(sess, crate)); - crate = time(time_passes, ~"extra injection", || front::std_inject::maybe_inject_libstd_ref(sess, crate)); diff --git a/src/librustc/front/intrinsic.rs b/src/librustc/front/intrinsic.rs deleted file mode 100644 index fcb08180a5ea2..0000000000000 --- a/src/librustc/front/intrinsic.rs +++ /dev/null @@ -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 or the MIT license -// , 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() -> *TyDesc { - unsafe { - rusti::get_tydesc::() 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() -> *(); - pub fn visit_tydesc(td: *TyDesc, tv: @TyVisitor); - } - } -} diff --git a/src/librustc/front/intrinsic_inject.rs b/src/librustc/front/intrinsic_inject.rs deleted file mode 100644 index 0caadc8572e90..0000000000000 --- a/src/librustc/front/intrinsic_inject.rs +++ /dev/null @@ -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 or the MIT license -// , 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_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 - } -} diff --git a/src/librustc/middle/lang_items.rs b/src/librustc/middle/lang_items.rs index 3a8d369469b17..d73b019c1ea76 100644 --- a/src/librustc/middle/lang_items.rs +++ b/src/librustc/middle/lang_items.rs @@ -76,16 +76,20 @@ pub enum LangItem { UnrecordBorrowFnLangItem, // 36 StartFnLangItem, // 37 + + TyDescStructLangItem, // 38 + TyVisitorTraitLangItem, // 39 + OpaqueStructLangItem, // 40 } pub struct LanguageItems { - items: [Option, ..38] + items: [Option, ..41] } impl LanguageItems { pub fn new() -> LanguageItems { LanguageItems { - items: [ None, ..38 ] + items: [ None, ..41 ] } } @@ -138,6 +142,10 @@ impl LanguageItems { 37 => "start", + 38 => "ty_desc", + 39 => "ty_visitor", + 40 => "opaque", + _ => "???" } } @@ -262,6 +270,15 @@ impl LanguageItems { pub fn start_fn(&const self) -> def_id { 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, @@ -313,6 +330,9 @@ fn LanguageItemCollector(crate: @crate, item_refs.insert(@"record_borrow", RecordBorrowFnLangItem as uint); item_refs.insert(@"unrecord_borrow", UnrecordBorrowFnLangItem 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 { crate: crate, diff --git a/src/librustc/middle/trans/foreign.rs b/src/librustc/middle/trans/foreign.rs index 10e63e6af7778..855610510bd90 100644 --- a/src/librustc/middle/trans/foreign.rs +++ b/src/librustc/middle/trans/foreign.rs @@ -681,9 +681,12 @@ pub fn trans_intrinsic(ccx: @mut CrateContext, let static_ti = get_tydesc(ccx, tp_ty); glue::lazily_emit_all_tydesc_glue(ccx, static_ti); - // FIXME (#3727): change this to ccx.tydesc_ty.ptr_to() when the - // core::sys copy of the get_tydesc interface dies off. - let td = PointerCast(bcx, static_ti.tydesc, Type::nil().ptr_to()); + // FIXME (#3730): ideally this shouldn't need a cast, + // but there's a circularity between translating rust types to llvm + // 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()); } "init" => { diff --git a/src/librustc/middle/trans/glue.rs b/src/librustc/middle/trans/glue.rs index e9febb51005cf..75a1221cca525 100644 --- a/src/librustc/middle/trans/glue.rs +++ b/src/librustc/middle/trans/glue.rs @@ -232,7 +232,7 @@ pub fn lazily_emit_tydesc_glue(ccx: @mut CrateContext, field: uint, ti: @mut tydesc_info) { 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) { return; @@ -338,9 +338,7 @@ pub fn call_tydesc_glue_full(bcx: block, } }; - Call(bcx, llfn, [C_null(Type::nil().ptr_to()), - C_null(bcx.ccx().tydesc_type.ptr_to().ptr_to()), - llrawptr]); + Call(bcx, llfn, [C_null(Type::nil().ptr_to()), llrawptr]); } // 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 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 llty = type_of(ccx, t); 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"); // As of this point, allow no more tydescs to be created. 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; for tyds.each_value |&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, - [ti.size, // size - ti.align, // align - take_glue, // take_glue - drop_glue, // drop_glue - free_glue, // free_glue - visit_glue, // visit_glue - shape, // shape - shape_tables]); // shape_tables + [ti.size, // size + ti.align, // align + take_glue, // take_glue + drop_glue, // drop_glue + free_glue, // free_glue + visit_glue]); // visit_glue unsafe { 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()) -} diff --git a/src/librustc/middle/trans/reflect.rs b/src/librustc/middle/trans/reflect.rs index cb68a2af92bb7..9e5510fc60586 100644 --- a/src/librustc/middle/trans/reflect.rs +++ b/src/librustc/middle/trans/reflect.rs @@ -274,9 +274,7 @@ impl Reflector { let repr = adt::represent_type(bcx.ccx(), t); let variants = ty::substd_enum_variants(ccx.tcx, did, substs); let llptrty = type_of(ccx, t).ptr_to(); - let (_, opaquety) = - ccx.tcx.intrinsic_defs.find_copy(&ccx.sess.ident_of("Opaque")) - .expect("Failed to resolve intrinsic::Opaque"); + let opaquety = ty::get_opaque_ty(ccx.tcx); let opaqueptrty = ty::mk_ptr(ccx.tcx, ty::mt { ty: opaquety, mutbl: ast::m_imm }); let make_get_disr = || { @@ -373,10 +371,8 @@ pub fn emit_calls_to_trait_visit_ty(bcx: block, visitor_val: ValueRef, visitor_trait_id: def_id) -> block { - use syntax::parse::token::special_idents::tydesc; let final = sub_block(bcx, "final"); - assert!(bcx.ccx().tcx.intrinsic_defs.contains_key(&tydesc)); - let (_, tydesc_ty) = bcx.ccx().tcx.intrinsic_defs.get_copy(&tydesc); + let tydesc_ty = ty::get_tydesc_ty(bcx.ccx().tcx); let tydesc_ty = type_of(bcx.ccx(), tydesc_ty); let mut r = Reflector { visitor_val: visitor_val, diff --git a/src/librustc/middle/trans/type_.rs b/src/librustc/middle/trans/type_.rs index 34a1503310912..64688ac413424 100644 --- a/src/librustc/middle/trans/type_.rs +++ b/src/librustc/middle/trans/type_.rs @@ -20,7 +20,6 @@ use middle::trans::base; use syntax::ast; use syntax::abi::{Architecture, X86, X86_64, Arm, Mips}; -use back::abi; use core::vec; use core::cast; @@ -189,25 +188,26 @@ impl Type { 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); return ty; } + pub fn glue_fn() -> Type { + Type::func([ Type::nil().ptr_to(), Type::i8p() ], + &Type::void()) + } + pub fn tydesc(arch: Architecture) -> Type { let mut tydesc = Type::named_struct("tydesc"); - let tydescpp = tydesc.ptr_to().ptr_to(); - let pvoid = Type::i8p(); - let glue_fn_ty = Type::func([ Type::nil().ptr_to(), tydescpp, pvoid ], - &Type::void()).ptr_to(); + let glue_fn_ty = Type::glue_fn().ptr_to(); let int_ty = Type::int(arch); let elems = [ int_ty, int_ty, - glue_fn_ty, glue_fn_ty, glue_fn_ty, glue_fn_ty, - pvoid, pvoid + glue_fn_ty, glue_fn_ty, glue_fn_ty, glue_fn_ty ]; tydesc.set_struct_body(elems, false); @@ -265,10 +265,6 @@ impl 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 { let tydesc_ptr = ctx.tydesc_type.ptr_to(); match store { diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index a367cf4c430a7..9e1a0def2eef0 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -44,7 +44,6 @@ use syntax::attr; use syntax::codemap::span; use syntax::codemap; use syntax::parse::token; -use syntax::parse::token::special_idents; use syntax::{ast, ast_map}; use syntax::opt_vec::OptVec; use syntax::opt_vec; @@ -276,8 +275,7 @@ struct ctxt_ { trait_defs: @mut HashMap, items: ast_map::map, - intrinsic_defs: @mut HashMap, - intrinsic_traits: @mut HashMap, + intrinsic_defs: @mut HashMap, freevars: freevars::freevar_map, tcache: type_cache, rcache: creader_cache, @@ -953,7 +951,6 @@ pub fn mk_ctxt(s: session::Session, node_type_substs: @mut HashMap::new(), trait_refs: @mut HashMap::new(), trait_defs: @mut HashMap::new(), - intrinsic_traits: @mut HashMap::new(), items: amap, intrinsic_defs: @mut HashMap::new(), freevars: freevars, @@ -4449,10 +4446,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) { - let ty_visitor_name = special_idents::ty_visitor; - assert!(tcx.intrinsic_traits.contains_key(&ty_visitor_name)); - let trait_ref = tcx.intrinsic_traits.get_copy(&ty_visitor_name); + let substs = substs { + self_r: None, + 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, mk_trait(tcx, trait_ref.def_id, copy trait_ref.substs, BoxTraitStore, ast::m_imm)) } diff --git a/src/librustc/middle/typeck/check/mod.rs b/src/librustc/middle/typeck/check/mod.rs index fa7959c7872b4..821daee8bfbf0 100644 --- a/src/librustc/middle/typeck/check/mod.rs +++ b/src/librustc/middle/typeck/check/mod.rs @@ -3506,13 +3506,15 @@ pub fn check_intrinsic_type(ccx: @mut CrateCtxt, it: @ast::foreign_item) { } "get_tydesc" => { - // FIXME (#3730): return *intrinsic::tydesc, not *() - (1u, ~[], ty::mk_nil_ptr(ccx.tcx)) + let tydesc_ty = ty::get_tydesc_ty(ccx.tcx); + let td_ptr = ty::mk_ptr(ccx.tcx, ty::mt { + ty: tydesc_ty, + mutbl: ast::m_imm + }); + (1u, ~[], td_ptr) } "visit_tydesc" => { - let tydesc_name = special_idents::tydesc; - assert!(tcx.intrinsic_defs.contains_key(&tydesc_name)); - let (_, tydesc_ty) = tcx.intrinsic_defs.get_copy(&tydesc_name); + let tydesc_ty = ty::get_tydesc_ty(ccx.tcx); let (_, visitor_object_ty) = ty::visitor_object_ty(tcx); let td_ptr = ty::mk_ptr(ccx.tcx, ty::mt { ty: tydesc_ty, diff --git a/src/librustc/middle/typeck/collect.rs b/src/librustc/middle/typeck/collect.rs index 7f820d11ac614..756bb4d1bb922 100644 --- a/src/librustc/middle/typeck/collect.rs +++ b/src/librustc/middle/typeck/collect.rs @@ -62,55 +62,16 @@ use syntax::opt_vec::OptVec; use syntax::opt_vec; pub fn collect_item_types(ccx: @mut CrateCtxt, crate: @ast::crate) { - - // FIXME (#2592): hooking into the "intrinsic" root module is crude. - // There ought to be a better approach. Attributes? - - for crate.node.module.items.iter().advance |crate_item| { - 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; - } + fn collect_intrinsic_type(ccx: @mut CrateCtxt, + lang_item: ast::def_id) { + let ty::ty_param_bounds_and_ty { ty: ty, _ } = + ccx.get_item_ty(lang_item); + ccx.tcx.intrinsic_defs.insert(lang_item, ty); } + collect_intrinsic_type(ccx, ccx.tcx.lang_items.ty_desc()); + collect_intrinsic_type(ccx, ccx.tcx.lang_items.opaque()); + visit::visit_crate( crate, ((), visit::mk_simple_visitor(@visit::SimpleVisitor { diff --git a/src/librustc/rustc.rc b/src/librustc/rustc.rc index d59a308beb537..20705b3d79750 100644 --- a/src/librustc/rustc.rc +++ b/src/librustc/rustc.rc @@ -86,7 +86,6 @@ pub mod front { pub mod config; pub mod test; pub mod std_inject; - pub mod intrinsic_inject; } pub mod back { diff --git a/src/libstd/at_vec.rs b/src/libstd/at_vec.rs index 2b846c923c48f..52115692dbce8 100644 --- a/src/libstd/at_vec.rs +++ b/src/libstd/at_vec.rs @@ -26,13 +26,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); } @@ -198,6 +201,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; @@ -259,7 +266,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::(), + rustrt::vec_reserve_shared_actual(get_tydesc::(), ptr, n as libc::size_t); } } diff --git a/src/libstd/cleanup.rs b/src/libstd/cleanup.rs index d1460b7a3c96b..ee9fdd3c62005 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 611b95a7745e4..c9e33219fa503 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,17 +59,11 @@ 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; @@ -125,7 +120,7 @@ unsafe fn is_safe_point(pc: *Word) -> Option { 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 d514612b5afd8..b71b3b503c2ac 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 d276abf0c8b3e..16ab4771d0de1 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 ab3f83d34d590..f39b5a00ed054 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(writer: @Writer, object: &T) { unsafe { let ptr = ptr::to_unsafe_ptr(object) as *c_void; - let tydesc = intrinsic::get_tydesc::(); + let tydesc = get_tydesc::(); 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 ce7ff87b44580..1e9f9aab8345c 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 79ea60cc22406..a1d6342323c64 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() -> *TypeDesc { - unsafe { intrinsics::get_tydesc::() as *TypeDesc } -} - -/// Returns a pointer to a type descriptor. -#[inline] -pub fn get_type_desc_val(_val: &T) -> *TypeDesc { - get_type_desc::() -} - /// Returns the size of a type #[inline] pub fn size_of() -> uint { diff --git a/src/libstd/unstable/exchange_alloc.rs b/src/libstd/unstable/exchange_alloc.rs index 3b35c2fb8047f..5c47901df4802 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 c38b013a75aa3..bd34574c3b7a4 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" { @@ -209,6 +333,9 @@ pub extern "rust-intrinsic" { pub fn pref_align_of() -> uint; /// Get a static pointer to a type descriptor. + #[cfg(not(stage0))] + pub fn get_tydesc() -> *TyDesc; + #[cfg(stage0)] pub fn get_tydesc() -> *(); /// Create a value initialized to zero. @@ -231,9 +358,8 @@ pub extern "rust-intrinsic" { /// Returns `true` if a type requires drop glue. pub fn needs_drop() -> 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 17eb7e8e82be2..fdf33df3a8a1a 100644 --- a/src/libstd/vec.rs +++ b/src/libstd/vec.rs @@ -31,6 +31,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; @@ -38,19 +42,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); } @@ -79,7 +86,7 @@ pub fn reserve(v: &mut ~[T], n: uint) { if capacity(v) < n { unsafe { let ptr: **raw::VecRepr = cast::transmute(v); - let td = sys::get_type_desc::(); + let td = get_tydesc::(); if ((**ptr).box_header.ref_count == managed::raw::RC_MANAGED_UNIQUE) { rustrt::vec_reserve_shared_actual(td, ptr, n as libc::size_t); diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs index 273a59f0a3dee..d40b96f077bb1 100644 --- a/src/libsyntax/parse/token.rs +++ b/src/libsyntax/parse/token.rs @@ -331,21 +331,18 @@ pub mod special_idents { pub static str : ident = ident { name: 19, ctxt: 0}; // for the type /* outside of libsyntax */ - pub static ty_visitor : ident = ident { name: 20, ctxt: 0}; - pub static arg : ident = ident { name: 21, ctxt: 0}; - pub static descrim : ident = ident { name: 22, ctxt: 0}; - pub static clownshoe_abi : ident = ident { name: 23, ctxt: 0}; - pub static clownshoe_stack_shim : ident = ident { name: 24, ctxt: 0}; - pub static tydesc : ident = ident { name: 25, ctxt: 0}; - pub static main : ident = ident { name: 26, ctxt: 0}; - pub static opaque : ident = ident { name: 27, ctxt: 0}; - pub static blk : ident = ident { name: 28, ctxt: 0}; - pub static statik : ident = ident { name: 29, ctxt: 0}; - pub static intrinsic : ident = ident { name: 30, ctxt: 0}; - pub static clownshoes_foreign_mod: ident = ident { name: 31, ctxt: 0}; - 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` + pub static arg : ident = ident { name: 20, ctxt: 0}; + pub static descrim : ident = ident { name: 21, ctxt: 0}; + pub static clownshoe_abi : ident = ident { name: 22, ctxt: 0}; + pub static clownshoe_stack_shim : ident = ident { name: 23, ctxt: 0}; + pub static main : ident = ident { name: 24, ctxt: 0}; + pub static opaque : ident = ident { name: 25, ctxt: 0}; + pub static blk : ident = ident { name: 26, ctxt: 0}; + pub static statik : ident = ident { name: 27, ctxt: 0}; + pub static clownshoes_foreign_mod: ident = ident { name: 28, ctxt: 0}; + pub static unnamed_field: ident = ident { name: 29, ctxt: 0}; + pub static c_abi: ident = ident { name: 30, ctxt: 0}; + pub static type_self: ident = ident { name: 31, ctxt: 0}; // `Self` } /** @@ -426,59 +423,56 @@ fn mk_fresh_ident_interner() -> @ident_interner { "tt", // 17 "matchers", // 18 "str", // 19 - "TyVisitor", // 20 - "arg", // 21 - "descrim", // 22 - "__rust_abi", // 23 - "__rust_stack_shim", // 24 - "TyDesc", // 25 - "main", // 26 - "", // 27 - "blk", // 28 - "static", // 29 - "intrinsic", // 30 - "__foreign_mod__", // 31 - "__field__", // 32 - "C", // 33 - "Self", // 34 - - "as", // 35 - "break", // 36 - "const", // 37 - "copy", // 38 - "do", // 39 - "else", // 40 - "enum", // 41 - "extern", // 42 - "false", // 43 - "fn", // 44 - "for", // 45 - "if", // 46 - "impl", // 47 - "let", // 48 - "__log", // 49 - "loop", // 50 - "match", // 51 - "mod", // 52 - "mut", // 53 - "once", // 54 - "priv", // 55 - "pub", // 56 - "pure", // 57 - "ref", // 58 - "return", // 59 - "static", // 29 -- also a special ident + "arg", // 20 + "descrim", // 21 + "__rust_abi", // 22 + "__rust_stack_shim", // 23 + "main", // 24 + "", // 25 + "blk", // 26 + "static", // 27 + "__foreign_mod__", // 28 + "__field__", // 29 + "C", // 30 + "Self", // 31 + + "as", // 32 + "break", // 33 + "const", // 34 + "copy", // 35 + "do", // 36 + "else", // 37 + "enum", // 38 + "extern", // 39 + "false", // 40 + "fn", // 41 + "for", // 42 + "if", // 43 + "impl", // 44 + "let", // 45 + "__log", // 46 + "loop", // 47 + "match", // 48 + "mod", // 49 + "mut", // 50 + "once", // 51 + "priv", // 52 + "pub", // 53 + "pure", // 54 + "ref", // 55 + "return", // 56 + "static", // 27 -- also a special ident "self", // 8 -- also a special ident - "struct", // 60 - "super", // 61 - "true", // 62 - "trait", // 63 - "type", // 64 - "unsafe", // 65 - "use", // 66 - "while", // 67 - - "be", // 68 + "struct", // 57 + "super", // 58 + "true", // 59 + "trait", // 60 + "type", // 61 + "unsafe", // 62 + "use", // 63 + "while", // 64 + + "be", // 65 ]; @ident_interner { @@ -612,42 +606,42 @@ pub mod keywords { impl Keyword { pub fn to_ident(&self) -> ident { match *self { - As => ident { name: 35, ctxt: 0 }, - Break => ident { name: 36, ctxt: 0 }, - Const => ident { name: 37, ctxt: 0 }, - Copy => ident { name: 38, ctxt: 0 }, - Do => ident { name: 39, ctxt: 0 }, - Else => ident { name: 40, ctxt: 0 }, - Enum => ident { name: 41, ctxt: 0 }, - Extern => ident { name: 42, ctxt: 0 }, - False => ident { name: 43, ctxt: 0 }, - Fn => ident { name: 44, ctxt: 0 }, - For => ident { name: 45, ctxt: 0 }, - If => ident { name: 46, ctxt: 0 }, - Impl => ident { name: 47, ctxt: 0 }, - Let => ident { name: 48, ctxt: 0 }, - __Log => ident { name: 49, ctxt: 0 }, - Loop => ident { name: 50, ctxt: 0 }, - Match => ident { name: 51, ctxt: 0 }, - Mod => ident { name: 52, ctxt: 0 }, - Mut => ident { name: 53, ctxt: 0 }, - Once => ident { name: 54, ctxt: 0 }, - Priv => ident { name: 55, ctxt: 0 }, - Pub => ident { name: 56, ctxt: 0 }, - Pure => ident { name: 57, ctxt: 0 }, - Ref => ident { name: 58, ctxt: 0 }, - Return => ident { name: 59, ctxt: 0 }, - Static => ident { name: 29, ctxt: 0 }, + As => ident { name: 32, ctxt: 0 }, + Break => ident { name: 33, ctxt: 0 }, + Const => ident { name: 34, ctxt: 0 }, + Copy => ident { name: 35, ctxt: 0 }, + Do => ident { name: 36, ctxt: 0 }, + Else => ident { name: 37, ctxt: 0 }, + Enum => ident { name: 38, ctxt: 0 }, + Extern => ident { name: 39, ctxt: 0 }, + False => ident { name: 40, ctxt: 0 }, + Fn => ident { name: 41, ctxt: 0 }, + For => ident { name: 42, ctxt: 0 }, + If => ident { name: 43, ctxt: 0 }, + Impl => ident { name: 44, ctxt: 0 }, + Let => ident { name: 45, ctxt: 0 }, + __Log => ident { name: 46, ctxt: 0 }, + Loop => ident { name: 47, ctxt: 0 }, + Match => ident { name: 48, ctxt: 0 }, + Mod => ident { name: 49, ctxt: 0 }, + Mut => ident { name: 50, ctxt: 0 }, + Once => ident { name: 51, ctxt: 0 }, + Priv => ident { name: 52, ctxt: 0 }, + Pub => ident { name: 53, ctxt: 0 }, + Pure => ident { name: 54, ctxt: 0 }, + Ref => ident { name: 55, ctxt: 0 }, + Return => ident { name: 56, ctxt: 0 }, + Static => ident { name: 27, ctxt: 0 }, Self => ident { name: 8, ctxt: 0 }, - Struct => ident { name: 60, ctxt: 0 }, - Super => ident { name: 61, ctxt: 0 }, - True => ident { name: 62, ctxt: 0 }, - Trait => ident { name: 63, ctxt: 0 }, - Type => ident { name: 64, ctxt: 0 }, - Unsafe => ident { name: 65, ctxt: 0 }, - Use => ident { name: 66, ctxt: 0 }, - While => ident { name: 67, ctxt: 0 }, - Be => ident { name: 68, ctxt: 0 }, + Struct => ident { name: 57, ctxt: 0 }, + Super => ident { name: 58, ctxt: 0 }, + True => ident { name: 59, ctxt: 0 }, + Trait => ident { name: 60, ctxt: 0 }, + Type => ident { name: 61, ctxt: 0 }, + Unsafe => ident { name: 62, ctxt: 0 }, + Use => ident { name: 63, ctxt: 0 }, + While => ident { name: 64, 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 { match *tok { token::IDENT(sid, false) => match sid.name { - 8 | 29 | 35 .. 68 => true, + 8 | 27 | 32 .. 65 => true, _ => false, }, _ => false @@ -673,7 +667,7 @@ pub fn is_any_keyword(tok: &Token) -> bool { pub fn is_strict_keyword(tok: &Token) -> bool { match *tok { token::IDENT(sid, false) => match sid.name { - 8 | 29 | 35 .. 67 => true, + 8 | 27 | 32 .. 64 => true, _ => false, }, _ => false, @@ -683,7 +677,7 @@ pub fn is_strict_keyword(tok: &Token) -> bool { pub fn is_reserved_keyword(tok: &Token) -> bool { match *tok { token::IDENT(sid, false) => match sid.name { - 68 => true, + 65 => true, _ => false, }, _ => false, diff --git a/src/rt/rust_builtin.cpp b/src/rt/rust_builtin.cpp index e476fa0ad5e07..8d771da32fc26 100644 --- a/src/rt/rust_builtin.cpp +++ b/src/rt/rust_builtin.cpp @@ -729,15 +729,6 @@ rust_task_deref(rust_task *task) { 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! extern "C" void rust_log_str(uint32_t level, const char *str, size_t size) { diff --git a/src/rt/rust_task.cpp b/src/rt/rust_task.cpp index fe1b4622137eb..81ae991623f8c 100644 --- a/src/rt/rust_task.cpp +++ b/src/rt/rust_task.cpp @@ -183,7 +183,11 @@ void task_start_wrapper(spawn_args *a) if(env) { // free the environment (which should be a unique closure). 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); } diff --git a/src/rt/rust_type.h b/src/rt/rust_type.h index 6d36d2c960a2d..30ff5f1fa54e2 100644 --- a/src/rt/rust_type.h +++ b/src/rt/rust_type.h @@ -25,7 +25,11 @@ typedef void (*CDECL spawn_fn)(rust_opaque_box*, void *); 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 // header; you can obtain a ptr via box_body() below. @@ -57,8 +61,6 @@ struct type_desc { glue_fn *drop_glue; glue_fn *free_glue; glue_fn *visit_glue; - const uint8_t *unused; - const uint8_t *unused2; }; extern "C" type_desc *rust_clone_type_desc(type_desc*); diff --git a/src/rt/rust_util.cpp b/src/rt/rust_util.cpp index 8d80a344063f2..4a15830e529a0 100644 --- a/src/rt/rust_util.cpp +++ b/src/rt/rust_util.cpp @@ -21,8 +21,6 @@ struct type_desc str_body_tydesc = { NULL, // drop_glue NULL, // free_glue NULL, // visit_glue - NULL, // shape - NULL, // shape_tables }; // diff --git a/src/rt/rustrt.def.in b/src/rt/rustrt.def.in index ba7ada04a2754..7fd948d2cd94e 100644 --- a/src/rt/rustrt.def.in +++ b/src/rt/rustrt.def.in @@ -174,7 +174,6 @@ rust_set_task_local_data rust_task_local_data_atexit rust_task_ref rust_task_deref -rust_call_tydesc_glue tdefl_compress_mem_to_heap tinfl_decompress_mem_to_heap rust_gc_metadata @@ -239,4 +238,4 @@ rust_valgrind_stack_deregister rust_take_env_lock rust_drop_env_lock rust_update_log_settings -rust_running_on_valgrind \ No newline at end of file +rust_running_on_valgrind diff --git a/src/test/run-pass/extern-pub.rs b/src/test/run-pass/extern-pub.rs index 29b0457fc0507..27c45893930ca 100644 --- a/src/test/run-pass/extern-pub.rs +++ b/src/test/run-pass/extern-pub.rs @@ -1,11 +1,5 @@ -use std::libc; -use std::sys; -use std::vec; - extern { - pub unsafe fn vec_reserve_shared_actual(t: *sys::TypeDesc, - v: **vec::raw::VecRepr, - n: libc::size_t); + pub unsafe fn free(p: *u8); } pub fn main() { diff --git a/src/test/run-pass/reflect-visit-data.rs b/src/test/run-pass/reflect-visit-data.rs index a8571ab73254b..176e49e0ea195 100644 --- a/src/test/run-pass/reflect-visit-data.rs +++ b/src/test/run-pass/reflect-visit-data.rs @@ -10,15 +10,14 @@ // xfail-fast -use std::bool; use std::int; use std::libc::c_void; use std::ptr; use std::sys; 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 movable_ptr { @@ -637,7 +636,9 @@ impl TyVisitor for my_visitor { } fn get_tydesc_for(_t: T) -> *TyDesc { - get_tydesc::() + unsafe { + get_tydesc::() + } } struct Triple { x: int, y: int, z: int } @@ -651,8 +652,8 @@ pub fn main() { vals: ~[]}); let v = ptr_visit_adaptor(Inner {inner: u}); let td = get_tydesc_for(r); - unsafe { error!("tydesc sz: %u, align: %u", - (*td).size, (*td).align); } + error!("tydesc sz: %u, align: %u", + (*td).size, (*td).align); let v = @v as @TyVisitor; visit_tydesc(td, v); @@ -661,8 +662,7 @@ pub fn main() { println(fmt!("val: %s", *s)); } error!("%?", u.vals.clone()); - assert!(u.vals == ~[ - ~"1", ~"2", ~"3", ~"true", ~"false", ~"5", ~"4", ~"3", ~"12" - ]); + assert_eq!(u.vals.clone(), + ~[ ~"1", ~"2", ~"3", ~"true", ~"false", ~"5", ~"4", ~"3", ~"12"]); } - } +} diff --git a/src/test/run-pass/reflect-visit-type.rs b/src/test/run-pass/reflect-visit-type.rs index 8a7fef9561441..bb1c92dfa8a73 100644 --- a/src/test/run-pass/reflect-visit-type.rs +++ b/src/test/run-pass/reflect-visit-type.rs @@ -8,141 +8,153 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// xfail-test -use intrinsic::{TyDesc, get_tydesc, visit_tydesc, TyVisitor}; -struct my_visitor(@mut { types: ~[str] }); +use std::unstable::intrinsics::{TyDesc, get_tydesc, visit_tydesc, TyVisitor, Opaque}; -impl TyVisitor for my_visitor { - fn visit_bot() -> bool { - self.types += ~["bot"]; +struct MyVisitor { + types: @mut ~[~str], +} + +impl TyVisitor for MyVisitor { + fn visit_bot(&self) -> bool { + self.types.push(~"bot"); error!("visited bot type"); true } - fn visit_nil() -> bool { - self.types += ~["nil"]; + fn visit_nil(&self) -> bool { + self.types.push(~"nil"); error!("visited nil type"); true } - fn visit_bool() -> bool { - self.types += ~["bool"]; + fn visit_bool(&self) -> bool { + self.types.push(~"bool"); error!("visited bool type"); true } - fn visit_int() -> bool { - self.types += ~["int"]; + fn visit_int(&self) -> bool { + self.types.push(~"int"); error!("visited int type"); true } - fn visit_i8() -> bool { - self.types += ~["i8"]; + fn visit_i8(&self) -> bool { + self.types.push(~"i8"); error!("visited i8 type"); true } - fn visit_i16() -> bool { - self.types += ~["i16"]; + fn visit_i16(&self) -> bool { + self.types.push(~"i16"); error!("visited i16 type"); true } - fn visit_i32() -> bool { true } - fn visit_i64() -> bool { true } - - fn visit_uint() -> bool { true } - fn visit_u8() -> bool { true } - fn visit_u16() -> bool { true } - fn visit_u32() -> bool { true } - fn visit_u64() -> bool { true } - - fn visit_float() -> bool { true } - fn visit_f32() -> bool { true } - fn visit_f64() -> bool { true } - - fn visit_char() -> bool { true } - fn visit_str() -> bool { true } - - fn visit_estr_box() -> bool { true } - fn visit_estr_uniq() -> bool { true } - fn visit_estr_slice() -> bool { true } - fn visit_estr_fixed(_sz: uint, _sz: uint, + fn visit_i32(&self) -> bool { true } + fn visit_i64(&self) -> bool { true } + + fn visit_uint(&self) -> bool { true } + fn visit_u8(&self) -> bool { true } + fn visit_u16(&self) -> bool { true } + fn visit_u32(&self) -> bool { true } + fn visit_u64(&self) -> bool { true } + + fn visit_float(&self) -> bool { true } + fn visit_f32(&self) -> bool { true } + fn visit_f64(&self) -> bool { true } + + fn visit_char(&self) -> bool { true } + fn visit_str(&self) -> bool { true } + + fn visit_estr_box(&self) -> bool { true } + fn visit_estr_uniq(&self) -> bool { true } + fn visit_estr_slice(&self) -> bool { true } + fn visit_estr_fixed(&self, + _sz: uint, _sz: uint, _align: uint) -> bool { true } - fn visit_box(_mtbl: uint, _inner: *TyDesc) -> bool { true } - fn visit_uniq(_mtbl: uint, _inner: *TyDesc) -> bool { true } - fn visit_ptr(_mtbl: uint, _inner: *TyDesc) -> bool { true } - fn visit_rptr(_mtbl: uint, _inner: *TyDesc) -> bool { true } - - fn visit_vec(_mtbl: uint, inner: *TyDesc) -> bool { - self.types += ~["["]; - visit_tydesc(inner, my_visitor(*self) as TyVisitor); - self.types += ~["]"]; + fn visit_box(&self, _mtbl: uint, _inner: *TyDesc) -> bool { true } + fn visit_uniq(&self, _mtbl: uint, _inner: *TyDesc) -> bool { true } + fn visit_ptr(&self, _mtbl: uint, _inner: *TyDesc) -> bool { true } + fn visit_rptr(&self, _mtbl: uint, _inner: *TyDesc) -> bool { true } + + fn visit_vec(&self, _mtbl: uint, _inner: *TyDesc) -> bool { true } + fn visit_unboxed_vec(&self, _mtbl: uint, _inner: *TyDesc) -> bool { true } + fn visit_evec_box(&self, _mtbl: uint, _inner: *TyDesc) -> bool { true } + fn visit_evec_uniq(&self, _mtbl: uint, inner: *TyDesc) -> bool { + self.types.push(~"["); + unsafe { + visit_tydesc(inner, (@*self) as @TyVisitor); + } + self.types.push(~"]"); true } - fn visit_unboxed_vec(_mtbl: uint, _inner: *TyDesc) -> bool { true } - fn visit_evec_box(_mtbl: uint, _inner: *TyDesc) -> bool { true } - 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, + fn visit_evec_slice(&self, _mtbl: uint, _inner: *TyDesc) -> bool { true } + fn visit_evec_fixed(&self, _n: uint, _sz: uint, _align: uint, _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 } - fn visit_rec_field(_i: uint, _name: &str, + fn visit_rec_field(&self, _i: uint, _name: &str, _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 } - fn visit_enter_class(_n_fields: uint, + fn visit_enter_class(&self, _n_fields: uint, _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 } - fn visit_leave_class(_n_fields: uint, + fn visit_leave_class(&self, _n_fields: uint, _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 } - fn visit_tup_field(_i: uint, _inner: *TyDesc) -> bool { true } - fn visit_leave_tup(_n_fields: uint, + fn visit_tup_field(&self, _i: uint, _inner: *TyDesc) -> bool { true } + fn visit_leave_tup(&self, _n_fields: uint, _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 } - fn visit_enter_enum_variant(_variant: uint, + fn visit_enter_enum_variant(&self, + _variant: uint, _disr_val: int, _n_fields: uint, _name: &str) -> bool { true } - fn visit_enum_variant_field(_i: uint, _inner: *TyDesc) -> bool { true } - fn visit_leave_enum_variant(_variant: uint, + fn visit_enum_variant_field(&self, _i: uint, _offset: uint, _inner: *TyDesc) -> bool { true } + fn visit_leave_enum_variant(&self, + _variant: uint, _disr_val: int, _n_fields: uint, _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 } - fn visit_enter_fn(_purity: uint, _proto: uint, + fn visit_enter_fn(&self, _purity: uint, _proto: uint, _n_inputs: uint, _retstyle: uint) -> bool { true } - fn visit_fn_input(_i: uint, _mode: uint, _inner: *TyDesc) -> bool { true } - fn visit_fn_output(_retstyle: uint, _inner: *TyDesc) -> bool { true } - fn visit_leave_fn(_purity: uint, _proto: uint, + fn visit_fn_input(&self, _i: uint, _mode: uint, _inner: *TyDesc) -> bool { true } + fn visit_fn_output(&self, _retstyle: uint, _inner: *TyDesc) -> bool { true } + fn visit_leave_fn(&self, _purity: uint, _proto: uint, _n_inputs: uint, _retstyle: uint) -> bool { true } - fn visit_trait() -> bool { true } - fn visit_var() -> bool { true } - fn visit_var_integral() -> bool { true } - fn visit_param(_i: uint) -> bool { true } - fn visit_self() -> bool { true } - fn visit_type() -> bool { true } - fn visit_opaque_box() -> bool { true } - fn visit_constr(_inner: *TyDesc) -> bool { true } - fn visit_closure_ptr(_ck: uint) -> bool { true } + fn visit_trait(&self) -> bool { true } + fn visit_var(&self) -> bool { true } + fn visit_var_integral(&self) -> bool { true } + fn visit_param(&self, _i: uint) -> bool { true } + fn visit_self(&self) -> bool { true } + fn visit_type(&self) -> bool { true } + fn visit_opaque_box(&self) -> bool { true } + fn visit_constr(&self, _inner: *TyDesc) -> bool { true } + fn visit_closure_ptr(&self, _ck: uint) -> bool { true } } -fn visit_ty(v: TyVisitor) { - visit_tydesc(get_tydesc::(), v); +fn visit_ty(v: @TyVisitor) { + unsafe { + visit_tydesc(get_tydesc::(), v); + } } pub fn main() { - let v = my_visitor(@mut {types: ~[]}); - let vv = v as TyVisitor; + let v = @MyVisitor {types: @mut ~[]}; + let vv = v as @TyVisitor; visit_ty::(vv); visit_ty::(vv); @@ -150,9 +162,8 @@ pub fn main() { visit_ty::(vv); visit_ty::<~[int]>(vv); - for (v.types.clone()).each {|s| - io::println(fmt!("type: %s", s)); + for v.types.iter().advance |&s| { + println(fmt!("type: %s", s)); } - assert!(v.types == ["bool", "int", "i8", "i16", - "[", "int", "]"]); + assert_eq!((*v.types).clone(), ~[~"bool", ~"int", ~"i8", ~"i16", ~"[", ~"int", ~"]"]); }