From f2c5642d134df70755e0aede94074767cd3958eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philipp=20Br=C3=BCschweiler?= Date: Wed, 19 Jun 2013 19:54:54 +0200 Subject: [PATCH 01/10] Fix get_tydesc() return type This fixes part of #3730, but not all. Also changes the TyDesc struct to be equivalent with the generated code, with the hope that the above issue may one day be closed for good, i.e. that the TyDesc type can completely be specified in the Rust sources and not be generated. --- src/librustc/front/intrinsic.rs | 16 ++++++++++++---- src/librustc/middle/trans/foreign.rs | 9 ++++++--- src/librustc/middle/trans/glue.rs | 5 ++--- src/librustc/middle/trans/type_.rs | 11 ++++++++--- src/librustc/middle/typeck/check/mod.rs | 10 ++++++++-- src/libstd/unstable/intrinsics.rs | 3 +++ 6 files changed, 39 insertions(+), 15 deletions(-) diff --git a/src/librustc/front/intrinsic.rs b/src/librustc/front/intrinsic.rs index fcb08180a5e..f19e3706253 100644 --- a/src/librustc/front/intrinsic.rs +++ b/src/librustc/front/intrinsic.rs @@ -20,14 +20,22 @@ pub mod intrinsic { // version in sys is no longer present. pub fn get_tydesc() -> *TyDesc { unsafe { - rusti::get_tydesc::() as *TyDesc + rusti::get_tydesc::() } } + pub type GlueFn = extern "Rust" fn(**TyDesc, *i8); + + // NB: this has to be kept in sync with the Rust ABI. pub struct TyDesc { size: uint, - align: uint - // Remaining fields not listed + align: uint, + take_glue: GlueFn, + drop_glue: GlueFn, + free_glue: GlueFn, + visit_glue: GlueFn, + shape: *i8, + shape_tables: *i8 } pub enum Opaque { } @@ -133,7 +141,7 @@ pub mod intrinsic { #[abi = "rust-intrinsic"] pub extern "rust-intrinsic" { - pub fn get_tydesc() -> *(); + pub fn get_tydesc() -> *TyDesc; pub fn visit_tydesc(td: *TyDesc, tv: @TyVisitor); } } diff --git a/src/librustc/middle/trans/foreign.rs b/src/librustc/middle/trans/foreign.rs index 10e63e6af77..855610510bd 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 e9febb51005..0930d355035 100644 --- a/src/librustc/middle/trans/glue.rs +++ b/src/librustc/middle/trans/glue.rs @@ -789,7 +789,6 @@ 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()) +pub fn type_of_glue_fn(ccx: &CrateContext) -> Type { + Type::glue_fn(ccx.tydesc_type) } diff --git a/src/librustc/middle/trans/type_.rs b/src/librustc/middle/trans/type_.rs index 34a15033109..764bdb026f4 100644 --- a/src/librustc/middle/trans/type_.rs +++ b/src/librustc/middle/trans/type_.rs @@ -189,18 +189,23 @@ impl Type { None => () } + // Bit of a kludge: pick the fn typeref out of the tydesc.. let ty = cx.tydesc_type.get_field(abi::tydesc_field_drop_glue); cx.tn.associate_type("glue_fn", &ty); return ty; } + pub fn glue_fn(tydesc: Type) -> Type { + let tydescpp = tydesc.ptr_to().ptr_to(); + Type::func([ Type::nil().ptr_to(), tydescpp, 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(tydesc).ptr_to(); let int_ty = Type::int(arch); diff --git a/src/librustc/middle/typeck/check/mod.rs b/src/librustc/middle/typeck/check/mod.rs index fa7959c7872..4c074ce197e 100644 --- a/src/librustc/middle/typeck/check/mod.rs +++ b/src/librustc/middle/typeck/check/mod.rs @@ -3506,8 +3506,14 @@ 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_name = special_idents::tydesc; + assert!(tcx.intrinsic_defs.contains_key(&tydesc_name)); + let (_, tydesc_ty) = tcx.intrinsic_defs.get_copy(&tydesc_name); + 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; diff --git a/src/libstd/unstable/intrinsics.rs b/src/libstd/unstable/intrinsics.rs index c38b013a75a..08fc90fa908 100644 --- a/src/libstd/unstable/intrinsics.rs +++ b/src/libstd/unstable/intrinsics.rs @@ -209,6 +209,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() -> *::intrinsic::TyDesc; + #[cfg(stage0)] pub fn get_tydesc() -> *(); /// Create a value initialized to zero. From 469f394b251feebfb16090303da59206ba25acc6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philipp=20Br=C3=BCschweiler?= Date: Thu, 20 Jun 2013 11:39:49 +0200 Subject: [PATCH 02/10] Remove intrinsic module To achieve this, the following changes were made: * Move TyDesc, TyVisitor and Opaque to std::unstable::intrinsics * Convert TyDesc, TyVisitor and Opaque to lang items instead of specially handling the intrinsics module * Removed TypeDesc, FreeGlue and get_type_desc() from sys Fixes #3475. --- src/libextra/arena.rs | 29 +++-- src/libextra/dbg.rs | 34 +++--- src/librustc/driver/driver.rs | 3 - src/librustc/front/intrinsic.rs | 148 ------------------------ src/librustc/front/intrinsic_inject.rs | 47 -------- src/librustc/middle/lang_items.rs | 24 +++- src/librustc/middle/trans/reflect.rs | 8 +- src/librustc/middle/ty.rs | 27 +++-- src/librustc/middle/typeck/check/mod.rs | 8 +- src/librustc/middle/typeck/collect.rs | 55 ++------- src/librustc/rustc.rc | 1 - src/libstd/at_vec.rs | 13 ++- src/libstd/cleanup.rs | 28 +++-- src/libstd/managed.rs | 2 +- src/libstd/reflect.rs | 6 +- src/libstd/repr.rs | 20 +++- src/libstd/rt/global_heap.rs | 10 +- src/libstd/sys.rs | 12 +- src/libstd/unstable/exchange_alloc.rs | 10 +- src/libstd/unstable/intrinsics.rs | 129 ++++++++++++++++++++- src/libstd/vec.rs | 15 ++- src/test/run-pass/extern-pub.rs | 6 +- src/test/run-pass/reflect-visit-data.rs | 20 ++-- 23 files changed, 298 insertions(+), 357 deletions(-) delete mode 100644 src/librustc/front/intrinsic.rs delete mode 100644 src/librustc/front/intrinsic_inject.rs diff --git a/src/libextra/arena.rs b/src/libextra/arena.rs index db4cf564bab..a7d5660cd2e 100644 --- a/src/libextra/arena.rs +++ b/src/libextra/arena.rs @@ -43,20 +43,27 @@ 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; +#[cfg(stage0)] +use intrinsic::{get_tydesc, TyDesc}; +#[cfg(not(stage0))] +use core::unstable::intrinsics::{get_tydesc, TyDesc}; + pub mod rustrt { use core::libc::size_t; - use core::sys::TypeDesc; + #[cfg(stage0)] + use intrinsic::{TyDesc}; + #[cfg(not(stage0))] + use core::unstable::intrinsics::{TyDesc}; pub extern { #[rust_stack] unsafe fn rust_call_tydesc_glue(root: *u8, - tydesc: *TypeDesc, + tydesc: *TyDesc, field: size_t); } } @@ -136,7 +143,7 @@ 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); @@ -148,7 +155,7 @@ unsafe fn destroy_chunk(chunk: &Chunk) { } // 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 +164,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 +209,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 +237,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 +256,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 cbd7cb5e3c0..43c4aecdd27 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/driver/driver.rs b/src/librustc/driver/driver.rs index 1a7041c0884..fbb273450df 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 f19e3706253..00000000000 --- a/src/librustc/front/intrinsic.rs +++ /dev/null @@ -1,148 +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::() - } - } - - pub type GlueFn = extern "Rust" fn(**TyDesc, *i8); - - // NB: this has to be kept in sync with the Rust ABI. - pub struct TyDesc { - size: uint, - align: uint, - take_glue: GlueFn, - drop_glue: GlueFn, - free_glue: GlueFn, - visit_glue: GlueFn, - shape: *i8, - shape_tables: *i8 - } - - 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() -> *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 0caadc8572e..00000000000 --- 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 3a8d369469b..d73b019c1ea 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/reflect.rs b/src/librustc/middle/trans/reflect.rs index cb68a2af92b..9e5510fc605 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/ty.rs b/src/librustc/middle/ty.rs index a367cf4c430..f12ecebc6d5 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 tydesc_lang_item = tcx.lang_items.opaque(); + tcx.intrinsic_defs.find_copy(&tydesc_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 4c074ce197e..821daee8bfb 100644 --- a/src/librustc/middle/typeck/check/mod.rs +++ b/src/librustc/middle/typeck/check/mod.rs @@ -3506,9 +3506,7 @@ pub fn check_intrinsic_type(ccx: @mut CrateCtxt, it: @ast::foreign_item) { } "get_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 td_ptr = ty::mk_ptr(ccx.tcx, ty::mt { ty: tydesc_ty, mutbl: ast::m_imm @@ -3516,9 +3514,7 @@ pub fn check_intrinsic_type(ccx: @mut CrateCtxt, it: @ast::foreign_item) { (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 7f820d11ac6..756bb4d1bb9 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 d59a308beb5..20705b3d797 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 2b846c923c4..52115692dbc 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 d1460b7a3c9..28aab9adad2 100644 --- a/src/libstd/cleanup.rs +++ b/src/libstd/cleanup.rs @@ -10,24 +10,18 @@ #[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, to_unsafe_ptr}; use repr::BoxRepr; -use sys::TypeDesc; use cast::transmute; #[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 +158,20 @@ fn debug_mem() -> bool { false } +#[cfg(stage0)] +unsafe fn call_drop_glue(tydesc: *::std::unstable::intrinsics::TyDesc, data: *i8) { + use sys::TypeDesc; + + let tydesc: *TypeDesc = transmute(tydesc); + let drop_glue: extern "Rust" fn(**TypeDesc, *i8) = transmute((*tydesc).drop_glue); + drop_glue(to_unsafe_ptr(&tydesc), data); +} + +#[cfg(not(stage0))] +unsafe fn call_drop_glue(tydesc: *::std::unstable::intrinsics::TyDesc, data: *i8) { + ((*tydesc).drop_glue)(to_unsafe_ptr(&tydesc), data); +} + /// Destroys all managed memory (i.e. @ boxes) held by the current task. #[cfg(not(test))] #[lang="annihilate"] @@ -205,9 +213,7 @@ 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)); + call_drop_glue((*box).header.type_desc, transmute(&(*box).data)); } } diff --git a/src/libstd/managed.rs b/src/libstd/managed.rs index d514612b5af..b71b3b503c2 100644 --- a/src/libstd/managed.rs +++ b/src/libstd/managed.rs @@ -15,7 +15,7 @@ use ptr::to_unsafe_ptr; #[cfg(not(test))] use cmp::{Eq, Ord}; pub mod raw { - use intrinsic::TyDesc; + use std::unstable::intrinsics::TyDesc; pub static RC_EXCHANGE_UNIQUE : uint = (-1) as uint; pub static RC_MANAGED_UNIQUE : uint = (-2) as uint; diff --git a/src/libstd/reflect.rs b/src/libstd/reflect.rs index d276abf0c8b..16ab4771d0d 100644 --- a/src/libstd/reflect.rs +++ b/src/libstd/reflect.rs @@ -16,8 +16,10 @@ Runtime type reflection #[allow(missing_doc)]; -use intrinsic::{TyDesc, TyVisitor}; -use intrinsic::Opaque; +#[cfg(stage0)] +use intrinsic::{Opaque, TyDesc, TyVisitor}; +#[cfg(not(stage0))] +use unstable::intrinsics::{Opaque, TyDesc, TyVisitor}; use libc::c_void; use sys; use vec; diff --git a/src/libstd/repr.rs b/src/libstd/repr.rs index ab3f83d34d5..f39b5a00ed0 100644 --- a/src/libstd/repr.rs +++ b/src/libstd/repr.rs @@ -19,9 +19,6 @@ More runtime type reflection use cast::transmute; use char; use container::Container; -use intrinsic; -use intrinsic::{TyDesc, TyVisitor, visit_tydesc}; -use intrinsic::Opaque; use io::{Writer, WriterUtil}; use iterator::IteratorUtil; use libc::c_void; @@ -34,6 +31,10 @@ use to_str::ToStr; use vec::raw::{VecRepr, SliceRepr}; use vec; use vec::{OwnedVector, UnboxedVecRepr}; +#[cfg(stage0)] +use intrinsic::{Opaque, TyDesc, TyVisitor, get_tydesc, visit_tydesc}; +#[cfg(not(stage0))] +use unstable::intrinsics::{Opaque, TyDesc, TyVisitor, get_tydesc, visit_tydesc}; #[cfg(test)] use io; @@ -564,6 +565,7 @@ impl TyVisitor for ReprVisitor { fn visit_self(&self) -> bool { true } fn visit_type(&self) -> bool { true } + #[cfg(not(stage0))] fn visit_opaque_box(&self) -> bool { self.writer.write_char('@'); do self.get::<&managed::raw::BoxRepr> |b| { @@ -571,6 +573,16 @@ impl TyVisitor for ReprVisitor { self.visit_ptr_inner(p, b.header.type_desc); } } + #[cfg(stage0)] + fn visit_opaque_box(&self) -> bool { + self.writer.write_char('@'); + do self.get::<&managed::raw::BoxRepr> |b| { + let p = ptr::to_unsafe_ptr(&b.data) as *c_void; + unsafe { + self.visit_ptr_inner(p, transmute(b.header.type_desc)); + } + } + } // Type no longer exists, vestigial function. fn visit_constr(&self, _inner: *TyDesc) -> bool { fail!(); } @@ -581,7 +593,7 @@ impl TyVisitor for ReprVisitor { pub fn write_repr(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 ce7ff87b445..1e9f9aab834 100644 --- a/src/libstd/rt/global_heap.rs +++ b/src/libstd/rt/global_heap.rs @@ -8,26 +8,22 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use sys::{TypeDesc, size_of}; +use sys::{size_of}; use libc::{c_void, size_t, uintptr_t}; use c_malloc = libc::malloc; use c_free = libc::free; use managed::raw::{BoxHeaderRepr, BoxRepr}; use cast::transmute; -use unstable::intrinsics::{atomic_xadd,atomic_xsub}; +use unstable::intrinsics::{atomic_xadd,atomic_xsub,TyDesc}; use ptr::null; -use intrinsic::TyDesc; -pub unsafe fn malloc(td: *TypeDesc, size: uint) -> *c_void { +pub unsafe fn malloc(td: *TyDesc, size: uint) -> *c_void { assert!(td.is_not_null()); let total_size = get_box_size(size, (*td).align); let p = c_malloc(total_size as size_t); assert!(p.is_not_null()); - // FIXME #3475: Converting between our two different tydesc types - let td: *TyDesc = transmute(td); - let box: &mut BoxRepr = transmute(p); box.header.ref_count = -1; // Exchange values not ref counted box.header.type_desc = td; diff --git a/src/libstd/sys.rs b/src/libstd/sys.rs index 79ea60cc224..7f80375c2f6 100644 --- a/src/libstd/sys.rs +++ b/src/libstd/sys.rs @@ -17,14 +17,13 @@ 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 +#[cfg(stage0)] pub struct TypeDesc { size: uint, align: uint, @@ -58,16 +57,11 @@ pub mod rustrt { * performing dark magick. */ #[inline] +#[cfg(stage0)] 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 3b35c2fb804..5c47901df48 100644 --- a/src/libstd/unstable/exchange_alloc.rs +++ b/src/libstd/unstable/exchange_alloc.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use sys::{TypeDesc, size_of}; +use sys::size_of; use libc::{c_void, size_t}; use c_malloc = libc::malloc; use c_free = libc::free; @@ -16,18 +16,18 @@ use managed::raw::{BoxHeaderRepr, BoxRepr}; use cast::transmute; use unstable::intrinsics::{atomic_xadd,atomic_xsub}; use ptr::null; +#[cfg(stage0)] use intrinsic::TyDesc; +#[cfg(not(stage0))] +use unstable::intrinsics::TyDesc; -pub unsafe fn malloc(td: *TypeDesc, size: uint) -> *c_void { +pub unsafe fn malloc(td: *TyDesc, size: uint) -> *c_void { assert!(td.is_not_null()); let total_size = get_box_size(size, (*td).align); let p = c_malloc(total_size as size_t); assert!(p.is_not_null()); - // FIXME #3475: Converting between our two different tydesc types - let td: *TyDesc = transmute(td); - let box: &mut BoxRepr = transmute(p); box.header.ref_count = -1; // Exchange values not ref counted box.header.type_desc = td; diff --git a/src/libstd/unstable/intrinsics.rs b/src/libstd/unstable/intrinsics.rs index 08fc90fa908..a51ba05710b 100644 --- a/src/libstd/unstable/intrinsics.rs +++ b/src/libstd/unstable/intrinsics.rs @@ -32,6 +32,128 @@ 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}; + +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, + shape: *i8, + shape_tables: *i8 +} + +#[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" { @@ -210,7 +332,7 @@ pub extern "rust-intrinsic" { /// Get a static pointer to a type descriptor. #[cfg(not(stage0))] - pub fn get_tydesc() -> *::intrinsic::TyDesc; + pub fn get_tydesc() -> *TyDesc; #[cfg(stage0)] pub fn get_tydesc() -> *(); @@ -234,9 +356,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 17eb7e8e82b..fdf33df3a8a 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/test/run-pass/extern-pub.rs b/src/test/run-pass/extern-pub.rs index 29b0457fc05..2d6cc2c78de 100644 --- a/src/test/run-pass/extern-pub.rs +++ b/src/test/run-pass/extern-pub.rs @@ -1,11 +1,7 @@ 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: *libc::c_void); } pub fn main() { diff --git a/src/test/run-pass/reflect-visit-data.rs b/src/test/run-pass/reflect-visit-data.rs index a8571ab7325..176e49e0ea1 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"]); } - } +} From 179ce398ea9e09920ace2264144422bb7e9efc02 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philipp=20Br=C3=BCschweiler?= Date: Thu, 20 Jun 2013 11:40:17 +0200 Subject: [PATCH 03/10] Fix and reenable the reflect-visit-type test --- src/test/run-pass/reflect-visit-type.rs | 171 +++++++++++++----------- 1 file changed, 91 insertions(+), 80 deletions(-) diff --git a/src/test/run-pass/reflect-visit-type.rs b/src/test/run-pass/reflect-visit-type.rs index 8a7fef95614..3b51abbd489 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_i32(&self) -> bool { true } + fn visit_i64(&self) -> 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_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() -> bool { true } - fn visit_f32() -> bool { true } - fn visit_f64() -> bool { true } + fn visit_float(&self) -> bool { true } + fn visit_f32(&self) -> bool { true } + fn visit_f64(&self) -> bool { true } - fn visit_char() -> bool { true } - fn visit_str() -> bool { true } + fn visit_char(&self) -> bool { true } + fn visit_str(&self) -> 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_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_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(_mtbl: uint, inner: *TyDesc) -> bool { - self.types += ~["["]; - visit_tydesc(inner, my_visitor(*self) as TyVisitor); - self.types += ~["]"]; + 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.each |&s| { + println(fmt!("type: %s", s)); } - assert!(v.types == ["bool", "int", "i8", "i16", - "[", "int", "]"]); + assert_eq!((*v.types).clone(), ~[~"bool", ~"int", ~"i8", ~"i16", ~"[", ~"int", ~"]"]); } From 8bf00333455a572bc4c48f947777ed2e7b57af09 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philipp=20Br=C3=BCschweiler?= Date: Thu, 20 Jun 2013 14:45:10 +0200 Subject: [PATCH 04/10] Remove unused shape fields from typedescs --- src/librustc/back/abi.rs | 4 +--- src/librustc/middle/trans/glue.rs | 18 ++++++------------ src/librustc/middle/trans/type_.rs | 3 +-- src/libstd/unstable/intrinsics.rs | 2 -- src/rt/rust_builtin.cpp | 7 +++---- src/rt/rust_type.h | 2 -- src/rt/rust_util.cpp | 2 -- 7 files changed, 11 insertions(+), 27 deletions(-) diff --git a/src/librustc/back/abi.rs b/src/librustc/back/abi.rs index 004170dea7f..8f15c74ed0e 100644 --- a/src/librustc/back/abi.rs +++ b/src/librustc/back/abi.rs @@ -49,9 +49,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; diff --git a/src/librustc/middle/trans/glue.rs b/src/librustc/middle/trans/glue.rs index 0930d355035..f9bffb4a36e 100644 --- a/src/librustc/middle/trans/glue.rs +++ b/src/librustc/middle/trans/glue.rs @@ -765,19 +765,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; diff --git a/src/librustc/middle/trans/type_.rs b/src/librustc/middle/trans/type_.rs index 764bdb026f4..fda8fb4a901 100644 --- a/src/librustc/middle/trans/type_.rs +++ b/src/librustc/middle/trans/type_.rs @@ -211,8 +211,7 @@ impl Type { 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); diff --git a/src/libstd/unstable/intrinsics.rs b/src/libstd/unstable/intrinsics.rs index a51ba05710b..84bb2a952f2 100644 --- a/src/libstd/unstable/intrinsics.rs +++ b/src/libstd/unstable/intrinsics.rs @@ -48,8 +48,6 @@ pub struct TyDesc { drop_glue: GlueFn, free_glue: GlueFn, visit_glue: GlueFn, - shape: *i8, - shape_tables: *i8 } #[lang="opaque"] diff --git a/src/rt/rust_builtin.cpp b/src/rt/rust_builtin.cpp index e476fa0ad5e..1a84325c7a9 100644 --- a/src/rt/rust_builtin.cpp +++ b/src/rt/rust_builtin.cpp @@ -732,10 +732,9 @@ rust_task_deref(rust_task *task) { // 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); + glue_fn *fn = (glue_fn*) tydesc[glue_index]; + if (fn) + fn(0, 0, root); } // Don't run on the Rust stack! diff --git a/src/rt/rust_type.h b/src/rt/rust_type.h index 6d36d2c960a..70b5c1dc6be 100644 --- a/src/rt/rust_type.h +++ b/src/rt/rust_type.h @@ -57,8 +57,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 8d80a344063..4a15830e529 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 }; // From 273f90566c26309c13ebe10278f8745e978250b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philipp=20Br=C3=BCschweiler?= Date: Thu, 20 Jun 2013 15:13:20 +0200 Subject: [PATCH 05/10] Small cleanups --- src/librustc/middle/trans/type_.rs | 7 +------ src/librustc/middle/ty.rs | 4 ++-- 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/src/librustc/middle/trans/type_.rs b/src/librustc/middle/trans/type_.rs index fda8fb4a901..7b02030078c 100644 --- a/src/librustc/middle/trans/type_.rs +++ b/src/librustc/middle/trans/type_.rs @@ -189,8 +189,7 @@ impl Type { None => () } - // Bit of a kludge: pick the fn typeref out of the tydesc.. - let ty = cx.tydesc_type.get_field(abi::tydesc_field_drop_glue); + let ty = Type::glue_fn(cx.tydesc_type).ptr_to(); cx.tn.associate_type("glue_fn", &ty); return ty; @@ -269,10 +268,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 f12ecebc6d5..9e1a0def2ee 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -4453,8 +4453,8 @@ pub fn get_tydesc_ty(tcx: ctxt) -> t { } pub fn get_opaque_ty(tcx: ctxt) -> t { - let tydesc_lang_item = tcx.lang_items.opaque(); - tcx.intrinsic_defs.find_copy(&tydesc_lang_item) + let opaque_lang_item = tcx.lang_items.opaque(); + tcx.intrinsic_defs.find_copy(&opaque_lang_item) .expect("Failed to resolve Opaque") } From 976c0b3dfb6a0da8a70958f157507b5dcf7c5ceb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philipp=20Br=C3=BCschweiler?= Date: Fri, 21 Jun 2013 10:00:49 +0200 Subject: [PATCH 06/10] Remove rust_call_tydesc_glue Towards #4812. Also includes some minor cleanups. --- src/libextra/arena.rs | 32 ++++++++------------------------ src/libstd/cleanup.rs | 18 +++--------------- src/libstd/gc.rs | 15 +++++---------- src/libstd/sys.rs | 23 ----------------------- src/rt/rust_builtin.cpp | 8 -------- src/rt/rustrt.def.in | 3 +-- 6 files changed, 17 insertions(+), 82 deletions(-) diff --git a/src/libextra/arena.rs b/src/libextra/arena.rs index a7d5660cd2e..3766af04656 100644 --- a/src/libextra/arena.rs +++ b/src/libextra/arena.rs @@ -41,37 +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; use core::uint; use core::vec; use core::unstable::intrinsics; +use core::unstable::intrinsics::{TyDesc}; + +#[cfg(not(stage0))] +use core::unstable::intrinsics::{get_tydesc}; #[cfg(stage0)] -use intrinsic::{get_tydesc, TyDesc}; -#[cfg(not(stage0))] -use core::unstable::intrinsics::{get_tydesc, TyDesc}; - -pub mod rustrt { - use core::libc::size_t; - #[cfg(stage0)] - use intrinsic::{TyDesc}; - #[cfg(not(stage0))] - use core::unstable::intrinsics::{TyDesc}; - - pub extern { - #[rust_stack] - unsafe fn rust_call_tydesc_glue(root: *u8, - tydesc: *TyDesc, - field: size_t); - } +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. @@ -150,8 +134,8 @@ unsafe fn destroy_chunk(chunk: &Chunk) { //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); + ((*tydesc).drop_glue)(&tydesc as **TyDesc, + ptr::offset(buf, start) as *i8); } // Find where the next tydesc lives diff --git a/src/libstd/cleanup.rs b/src/libstd/cleanup.rs index 28aab9adad2..557a2fbc4ae 100644 --- a/src/libstd/cleanup.rs +++ b/src/libstd/cleanup.rs @@ -158,20 +158,6 @@ fn debug_mem() -> bool { false } -#[cfg(stage0)] -unsafe fn call_drop_glue(tydesc: *::std::unstable::intrinsics::TyDesc, data: *i8) { - use sys::TypeDesc; - - let tydesc: *TypeDesc = transmute(tydesc); - let drop_glue: extern "Rust" fn(**TypeDesc, *i8) = transmute((*tydesc).drop_glue); - drop_glue(to_unsafe_ptr(&tydesc), data); -} - -#[cfg(not(stage0))] -unsafe fn call_drop_glue(tydesc: *::std::unstable::intrinsics::TyDesc, data: *i8) { - ((*tydesc).drop_glue)(to_unsafe_ptr(&tydesc), data); -} - /// Destroys all managed memory (i.e. @ boxes) held by the current task. #[cfg(not(test))] #[lang="annihilate"] @@ -213,7 +199,9 @@ pub unsafe fn annihilate() { // callback, as the original value may have been freed. for each_live_alloc(false) |box, uniq| { if !uniq { - call_drop_glue((*box).header.type_desc, transmute(&(*box).data)); + let tydesc = (*box).header.type_desc; + let data = transmute(&(*box).data); + ((*tydesc).drop_glue)(to_unsafe_ptr(&tydesc), data); } } diff --git a/src/libstd/gc.rs b/src/libstd/gc.rs index 611b95a7745..2a211484e73 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; @@ -364,7 +359,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); + ((*tydesc).drop_glue)(&tydesc as **TyDesc, *root as *i8); } } } diff --git a/src/libstd/sys.rs b/src/libstd/sys.rs index 7f80375c2f6..a1d6342323c 100644 --- a/src/libstd/sys.rs +++ b/src/libstd/sys.rs @@ -22,17 +22,6 @@ use repr; use str; use unstable::intrinsics; -// Corresponds to runtime type_desc type -#[cfg(stage0)] -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: *(), @@ -50,18 +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] -#[cfg(stage0)] -pub fn get_type_desc() -> *TypeDesc { - unsafe { intrinsics::get_tydesc::() as *TypeDesc } -} - /// Returns the size of a type #[inline] pub fn size_of() -> uint { diff --git a/src/rt/rust_builtin.cpp b/src/rt/rust_builtin.cpp index 1a84325c7a9..8d771da32fc 100644 --- a/src/rt/rust_builtin.cpp +++ b/src/rt/rust_builtin.cpp @@ -729,14 +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) { - glue_fn *fn = (glue_fn*) tydesc[glue_index]; - if (fn) - 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/rustrt.def.in b/src/rt/rustrt.def.in index ba7ada04a27..7fd948d2cd9 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 From 1b76bac41de9f52295a99db21abdd1ad5b0fc231 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philipp=20Br=C3=BCschweiler?= Date: Fri, 21 Jun 2013 13:01:15 +0200 Subject: [PATCH 07/10] syntax: Remove unused tokens TyDesc, TyVisitor and intrinsic are not used anymore. --- src/libsyntax/parse/token.rs | 200 +++++++++++++++++------------------ 1 file changed, 97 insertions(+), 103 deletions(-) diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs index 273a59f0a3d..d40b96f077b 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 + "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", // 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 + "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 + "struct", // 57 + "super", // 58 + "true", // 59 + "trait", // 60 + "type", // 61 + "unsafe", // 62 + "use", // 63 + "while", // 64 - "be", // 68 + "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, From e2f1049bd5f041f1f219d683e4e29e32ca30cd1c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philipp=20Br=C3=BCschweiler?= Date: Sat, 22 Jun 2013 21:36:00 +0200 Subject: [PATCH 08/10] Remove unused TyDesc parameter from the glue functions To remove the environment pointer, support for function pointers without an environment argument is needed (i.e. a fixed version of #6661). --- src/libextra/arena.rs | 16 ++++++++++++++-- src/librustc/back/abi.rs | 13 ------------- src/librustc/middle/trans/glue.rs | 14 ++++---------- src/librustc/middle/trans/type_.rs | 11 ++++------- src/libstd/cleanup.rs | 18 ++++++++++++++++-- src/libstd/gc.rs | 15 ++++++++++++++- src/libstd/unstable/intrinsics.rs | 4 ++++ src/rt/rust_task.cpp | 6 +++++- src/rt/rust_type.h | 6 +++++- 9 files changed, 66 insertions(+), 37 deletions(-) diff --git a/src/libextra/arena.rs b/src/libextra/arena.rs index 3766af04656..cec3a2c1e95 100644 --- a/src/libextra/arena.rs +++ b/src/libextra/arena.rs @@ -115,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) { @@ -134,8 +147,7 @@ unsafe fn destroy_chunk(chunk: &Chunk) { //debug!("freeing object: idx = %u, size = %u, align = %u, done = %b", // start, size, align, is_done); if is_done { - ((*tydesc).drop_glue)(&tydesc as **TyDesc, - ptr::offset(buf, start) as *i8); + call_drop_glue(tydesc, ptr::offset(buf, start) as *i8); } // Find where the next tydesc lives diff --git a/src/librustc/back/abi.rs b/src/librustc/back/abi.rs index 8f15c74ed0e..05b6e90c682 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; @@ -69,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/middle/trans/glue.rs b/src/librustc/middle/trans/glue.rs index f9bffb4a36e..75a1221cca5 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; @@ -782,7 +780,3 @@ pub fn emit_tydescs(ccx: &mut CrateContext) { } }; } - -pub fn type_of_glue_fn(ccx: &CrateContext) -> Type { - Type::glue_fn(ccx.tydesc_type) -} diff --git a/src/librustc/middle/trans/type_.rs b/src/librustc/middle/trans/type_.rs index 7b02030078c..64688ac4134 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,22 +188,20 @@ impl Type { None => () } - let ty = Type::glue_fn(cx.tydesc_type).ptr_to(); + let ty = Type::glue_fn(); cx.tn.associate_type("glue_fn", &ty); return ty; } - pub fn glue_fn(tydesc: Type) -> Type { - let tydescpp = tydesc.ptr_to().ptr_to(); - Type::func([ Type::nil().ptr_to(), tydescpp, Type::i8p() ], + 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 pvoid = Type::i8p(); - let glue_fn_ty = Type::glue_fn(tydesc).ptr_to(); + let glue_fn_ty = Type::glue_fn().ptr_to(); let int_ty = Type::int(arch); diff --git a/src/libstd/cleanup.rs b/src/libstd/cleanup.rs index 557a2fbc4ae..ee9fdd3c620 100644 --- a/src/libstd/cleanup.rs +++ b/src/libstd/cleanup.rs @@ -11,9 +11,10 @@ #[doc(hidden)]; use libc::{c_char, intptr_t, uintptr_t}; -use ptr::{mut_null, to_unsafe_ptr}; +use ptr::{mut_null}; use repr::BoxRepr; use cast::transmute; +use unstable::intrinsics::TyDesc; #[cfg(not(test))] use unstable::lang::clear_task_borrow_list; /** @@ -158,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"] @@ -201,7 +215,7 @@ pub unsafe fn annihilate() { if !uniq { let tydesc = (*box).header.type_desc; let data = transmute(&(*box).data); - ((*tydesc).drop_glue)(to_unsafe_ptr(&tydesc), data); + call_drop_glue(tydesc, data); } } diff --git a/src/libstd/gc.rs b/src/libstd/gc.rs index 2a211484e73..c9e33219fa5 100644 --- a/src/libstd/gc.rs +++ b/src/libstd/gc.rs @@ -316,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. @@ -359,7 +372,7 @@ pub fn cleanup_stack_for_failure() { // FIXME #4420: Destroy this box // FIXME #4330: Destroy this box } else { - ((*tydesc).drop_glue)(&tydesc as **TyDesc, *root as *i8); + call_drop_glue(tydesc, *root as *i8); } } } diff --git a/src/libstd/unstable/intrinsics.rs b/src/libstd/unstable/intrinsics.rs index 84bb2a952f2..bd34574c3b7 100644 --- a/src/libstd/unstable/intrinsics.rs +++ b/src/libstd/unstable/intrinsics.rs @@ -36,6 +36,10 @@ A quick refresher on memory ordering: #[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. diff --git a/src/rt/rust_task.cpp b/src/rt/rust_task.cpp index fe1b4622137..81ae991623f 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 70b5c1dc6be..30ff5f1fa54 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. From ce888a505524937ca9aa91370e204bb28fe6ef7f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philipp=20Br=C3=BCschweiler?= Date: Sun, 23 Jun 2013 17:15:37 +0200 Subject: [PATCH 09/10] Fix reflect-visit-type for iterator changes --- src/test/run-pass/reflect-visit-type.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/run-pass/reflect-visit-type.rs b/src/test/run-pass/reflect-visit-type.rs index 3b51abbd489..bb1c92dfa8a 100644 --- a/src/test/run-pass/reflect-visit-type.rs +++ b/src/test/run-pass/reflect-visit-type.rs @@ -162,7 +162,7 @@ pub fn main() { visit_ty::(vv); visit_ty::<~[int]>(vv); - for v.types.each |&s| { + for v.types.iter().advance |&s| { println(fmt!("type: %s", s)); } assert_eq!((*v.types).clone(), ~[~"bool", ~"int", ~"i8", ~"i16", ~"[", ~"int", ~"]"]); From f8ae3cdcaacb29c7b56e546a9ddab1396b615f8f Mon Sep 17 00:00:00 2001 From: Philipp Brueschweiler Date: Mon, 24 Jun 2013 19:14:20 +0200 Subject: [PATCH 10/10] Fix test failure on windows This patch ensures that the multiple extern definitions of `free` in the run-pass tests have the same declaration, working around #7352. --- src/test/run-pass/extern-pub.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/test/run-pass/extern-pub.rs b/src/test/run-pass/extern-pub.rs index 2d6cc2c78de..27c45893930 100644 --- a/src/test/run-pass/extern-pub.rs +++ b/src/test/run-pass/extern-pub.rs @@ -1,7 +1,5 @@ -use std::libc; - extern { - pub unsafe fn free(p: *libc::c_void); + pub unsafe fn free(p: *u8); } pub fn main() {