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.
This commit is contained in:
parent
f2c5642d13
commit
469f394b25
23 changed files with 298 additions and 357 deletions
|
@ -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::<T>();
|
||||
let tydesc = get_tydesc::<T>();
|
||||
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::<T>();
|
||||
let tydesc = get_tydesc::<T>();
|
||||
let (ty_ptr, ptr) =
|
||||
self.alloc_nonpod_inner((*tydesc).size, (*tydesc).align);
|
||||
let ty_ptr: *mut uint = transmute(ty_ptr);
|
||||
|
|
|
@ -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<T>() {
|
||||
unsafe {
|
||||
rustrt::debug_tydesc(sys::get_type_desc::<T>());
|
||||
rustrt::debug_tydesc(get_tydesc::<T>());
|
||||
}
|
||||
}
|
||||
|
||||
pub fn debug_opaque<T>(x: T) {
|
||||
unsafe {
|
||||
rustrt::debug_opaque(sys::get_type_desc::<T>(), transmute(&x));
|
||||
rustrt::debug_opaque(get_tydesc::<T>(), transmute(&x));
|
||||
}
|
||||
}
|
||||
|
||||
pub fn debug_box<T>(x: @T) {
|
||||
unsafe {
|
||||
rustrt::debug_box(sys::get_type_desc::<T>(), transmute(&x));
|
||||
rustrt::debug_box(get_tydesc::<T>(), transmute(&x));
|
||||
}
|
||||
}
|
||||
|
||||
pub fn debug_tag<T>(x: T) {
|
||||
unsafe {
|
||||
rustrt::debug_tag(sys::get_type_desc::<T>(), transmute(&x));
|
||||
rustrt::debug_tag(get_tydesc::<T>(), transmute(&x));
|
||||
}
|
||||
}
|
||||
|
||||
pub fn debug_fn<T>(x: T) {
|
||||
unsafe {
|
||||
rustrt::debug_fn(sys::get_type_desc::<T>(), transmute(&x));
|
||||
rustrt::debug_fn(get_tydesc::<T>(), transmute(&x));
|
||||
}
|
||||
}
|
||||
|
||||
pub unsafe fn ptr_cast<T, U>(x: @T) -> @U {
|
||||
transmute(
|
||||
rustrt::debug_ptrcast(sys::get_type_desc::<T>(), transmute(x)))
|
||||
rustrt::debug_ptrcast(get_tydesc::<T>(), transmute(x)))
|
||||
}
|
||||
|
||||
/// Triggers a debugger breakpoint
|
||||
|
|
|
@ -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));
|
||||
|
||||
|
|
|
@ -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 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// NB: this file is include_str!'ed into the compiler, re-parsed
|
||||
// and injected into each crate the compiler builds. Keep it small.
|
||||
|
||||
pub mod intrinsic {
|
||||
#[allow(missing_doc)];
|
||||
|
||||
pub use intrinsic::rusti::visit_tydesc;
|
||||
|
||||
// FIXME (#3727): remove this when the interface has settled and the
|
||||
// version in sys is no longer present.
|
||||
pub fn get_tydesc<T>() -> *TyDesc {
|
||||
unsafe {
|
||||
rusti::get_tydesc::<T>()
|
||||
}
|
||||
}
|
||||
|
||||
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<T>() -> *TyDesc;
|
||||
pub fn visit_tydesc(td: *TyDesc, tv: @TyVisitor);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,47 +0,0 @@
|
|||
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
use core::prelude::*;
|
||||
|
||||
use core::vec;
|
||||
use driver::session::Session;
|
||||
use syntax::parse;
|
||||
use syntax::ast;
|
||||
use syntax::codemap::spanned;
|
||||
|
||||
pub fn inject_intrinsic(sess: Session, crate: @ast::crate) -> @ast::crate {
|
||||
let intrinsic_module = include_str!("intrinsic.rs").to_managed();
|
||||
|
||||
let item = parse::parse_item_from_source_str(@"<intrinsic>",
|
||||
intrinsic_module,
|
||||
/*bad*/copy sess.opts.cfg,
|
||||
~[],
|
||||
sess.parse_sess);
|
||||
let item =
|
||||
match item {
|
||||
Some(i) => i,
|
||||
None => {
|
||||
sess.fatal("no item found in intrinsic module");
|
||||
}
|
||||
};
|
||||
|
||||
let items = vec::append(~[item], crate.node.module.items);
|
||||
|
||||
@spanned {
|
||||
node: ast::crate_ {
|
||||
module: ast::_mod {
|
||||
items: items,
|
||||
.. /*bad*/copy crate.node.module
|
||||
},
|
||||
.. /*bad*/copy crate.node
|
||||
},
|
||||
.. /*bad*/copy *crate
|
||||
}
|
||||
}
|
|
@ -76,16 +76,20 @@ pub enum LangItem {
|
|||
UnrecordBorrowFnLangItem, // 36
|
||||
|
||||
StartFnLangItem, // 37
|
||||
|
||||
TyDescStructLangItem, // 38
|
||||
TyVisitorTraitLangItem, // 39
|
||||
OpaqueStructLangItem, // 40
|
||||
}
|
||||
|
||||
pub struct LanguageItems {
|
||||
items: [Option<def_id>, ..38]
|
||||
items: [Option<def_id>, ..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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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<def_id, @TraitDef>,
|
||||
|
||||
items: ast_map::map,
|
||||
intrinsic_defs: @mut HashMap<ast::ident, (ast::def_id, t)>,
|
||||
intrinsic_traits: @mut HashMap<ast::ident, @TraitRef>,
|
||||
intrinsic_defs: @mut HashMap<ast::def_id, t>,
|
||||
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))
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -86,7 +86,6 @@ pub mod front {
|
|||
pub mod config;
|
||||
pub mod test;
|
||||
pub mod std_inject;
|
||||
pub mod intrinsic_inject;
|
||||
}
|
||||
|
||||
pub mod back {
|
||||
|
|
|
@ -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::<T>(),
|
||||
rustrt::vec_reserve_shared_actual(get_tydesc::<T>(),
|
||||
ptr, n as libc::size_t);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -19,9 +19,6 @@ More runtime type reflection
|
|||
use cast::transmute;
|
||||
use char;
|
||||
use container::Container;
|
||||
use intrinsic;
|
||||
use intrinsic::{TyDesc, TyVisitor, visit_tydesc};
|
||||
use intrinsic::Opaque;
|
||||
use io::{Writer, WriterUtil};
|
||||
use iterator::IteratorUtil;
|
||||
use libc::c_void;
|
||||
|
@ -34,6 +31,10 @@ use to_str::ToStr;
|
|||
use vec::raw::{VecRepr, SliceRepr};
|
||||
use vec;
|
||||
use vec::{OwnedVector, UnboxedVecRepr};
|
||||
#[cfg(stage0)]
|
||||
use intrinsic::{Opaque, TyDesc, TyVisitor, get_tydesc, visit_tydesc};
|
||||
#[cfg(not(stage0))]
|
||||
use unstable::intrinsics::{Opaque, TyDesc, TyVisitor, get_tydesc, visit_tydesc};
|
||||
|
||||
#[cfg(test)] use io;
|
||||
|
||||
|
@ -564,6 +565,7 @@ impl TyVisitor for ReprVisitor {
|
|||
fn visit_self(&self) -> bool { true }
|
||||
fn visit_type(&self) -> bool { true }
|
||||
|
||||
#[cfg(not(stage0))]
|
||||
fn visit_opaque_box(&self) -> bool {
|
||||
self.writer.write_char('@');
|
||||
do self.get::<&managed::raw::BoxRepr> |b| {
|
||||
|
@ -571,6 +573,16 @@ impl TyVisitor for ReprVisitor {
|
|||
self.visit_ptr_inner(p, b.header.type_desc);
|
||||
}
|
||||
}
|
||||
#[cfg(stage0)]
|
||||
fn visit_opaque_box(&self) -> bool {
|
||||
self.writer.write_char('@');
|
||||
do self.get::<&managed::raw::BoxRepr> |b| {
|
||||
let p = ptr::to_unsafe_ptr(&b.data) as *c_void;
|
||||
unsafe {
|
||||
self.visit_ptr_inner(p, transmute(b.header.type_desc));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Type no longer exists, vestigial function.
|
||||
fn visit_constr(&self, _inner: *TyDesc) -> bool { fail!(); }
|
||||
|
@ -581,7 +593,7 @@ impl TyVisitor for ReprVisitor {
|
|||
pub fn write_repr<T>(writer: @Writer, object: &T) {
|
||||
unsafe {
|
||||
let ptr = ptr::to_unsafe_ptr(object) as *c_void;
|
||||
let tydesc = intrinsic::get_tydesc::<T>();
|
||||
let tydesc = get_tydesc::<T>();
|
||||
let u = ReprVisitor(ptr, writer);
|
||||
let v = reflect::MovePtrAdaptor(u);
|
||||
visit_tydesc(tydesc, @v as @TyVisitor)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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<T>() -> *TypeDesc {
|
||||
unsafe { intrinsics::get_tydesc::<T>() as *TypeDesc }
|
||||
}
|
||||
|
||||
/// Returns a pointer to a type descriptor.
|
||||
#[inline]
|
||||
pub fn get_type_desc_val<T>(_val: &T) -> *TypeDesc {
|
||||
get_type_desc::<T>()
|
||||
}
|
||||
|
||||
/// Returns the size of a type
|
||||
#[inline]
|
||||
pub fn size_of<T>() -> uint {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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<T>() -> *::intrinsic::TyDesc;
|
||||
pub fn get_tydesc<T>() -> *TyDesc;
|
||||
#[cfg(stage0)]
|
||||
pub fn get_tydesc<T>() -> *();
|
||||
|
||||
|
@ -234,9 +356,8 @@ pub extern "rust-intrinsic" {
|
|||
/// Returns `true` if a type requires drop glue.
|
||||
pub fn needs_drop<T>() -> bool;
|
||||
|
||||
// XXX: intrinsic uses legacy modes and has reference to TyDesc
|
||||
// and TyVisitor which are in librustc
|
||||
//fn visit_tydesc(++td: *TyDesc, &&tv: TyVisitor) -> ();
|
||||
#[cfg(not(stage0))]
|
||||
pub fn visit_tydesc(td: *TyDesc, tv: @TyVisitor);
|
||||
|
||||
pub fn frame_address(f: &once fn(*u8));
|
||||
|
||||
|
|
|
@ -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<T>(v: &mut ~[T], n: uint) {
|
|||
if capacity(v) < n {
|
||||
unsafe {
|
||||
let ptr: **raw::VecRepr = cast::transmute(v);
|
||||
let td = sys::get_type_desc::<T>();
|
||||
let td = get_tydesc::<T>();
|
||||
if ((**ptr).box_header.ref_count ==
|
||||
managed::raw::RC_MANAGED_UNIQUE) {
|
||||
rustrt::vec_reserve_shared_actual(td, ptr, n as libc::size_t);
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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: T) -> *TyDesc {
|
||||
get_tydesc::<T>()
|
||||
unsafe {
|
||||
get_tydesc::<T>()
|
||||
}
|
||||
}
|
||||
|
||||
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"]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue