(index<- )        ./libstd/reflect.rs

    git branch:    * master           5200215 auto merge of #14035 : alexcrichton/rust/experimental, r=huonw
    modified:    Fri May  9 13:02:28 2014
   1  // Copyright 2012 The Rust Project Developers. See the COPYRIGHT
   2  // file at the top-level directory of this distribution and at
   3  // http://rust-lang.org/COPYRIGHT.
   4  //
   5  // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
   6  // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
   7  // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
   8  // option. This file may not be copied, modified, or distributed
   9  // except according to those terms.
  10  
  11  /*!
  12  
  13  Runtime type reflection
  14  
  15  */
  16  
  17  #![allow(missing_doc)]
  18  
  19  use intrinsics::{Disr, Opaque, TyDesc, TyVisitor};
  20  use mem;
  21  use owned::Box;
  22  
  23  /**
  24   * Trait for visitor that wishes to reflect on data. To use this, create a
  25   * struct that encapsulates the set of pointers you wish to walk through a
  26   * data structure, and implement both `MovePtr` for it as well as `TyVisitor`;
  27   * then build a MovePtrAdaptor wrapped around your struct.
  28   */
  29  pub trait MovePtr {
  30      fn move_ptr(&mut self, adjustment: |*u8| -> *u8);
  31      fn push_ptr(&mut self);
  32      fn pop_ptr(&mut self);
  33  }
  34  
  35  /// Helper function for alignment calculation.
  36  #[inline]
  37  pub fn align(size: uint, align: uint) -> uint {
  38      ((size + align) - 1u) & !(align - 1u)
  39  }
  40  
  41  /// Adaptor to wrap around visitors implementing MovePtr.
  42  pub struct MovePtrAdaptor<V> {
  43      inner: V
  44  }
  45  pub fn MovePtrAdaptor<V:TyVisitor + MovePtr>(vV) -> MovePtrAdaptor<V> {
  46      MovePtrAdaptor { inner: v }
  47  }
  48  
  49  impl<V:TyVisitor + MovePtr> MovePtrAdaptor<V> {
  50      #[inline]
  51      pub fn bump(&mut self, szuint) {
  52          self.inner.move_ptr(|p| ((p as uint) + sz) as *u8)
  53      }
  54  
  55      #[inline]
  56      pub fn align(&mut self, auint) {
  57          self.inner.move_ptr(|p| align(p as uint, a) as *u8)
  58      }
  59  
  60      #[inline]
  61      pub fn align_to<T>(&mut self) {
  62          self.align(mem::min_align_of::<T>());
  63      }
  64  
  65      #[inline]
  66      pub fn bump_past<T>(&mut self) {
  67          self.bump(mem::size_of::<T>());
  68      }
  69  
  70      pub fn unwrap(self) -> V { self.inner }
  71  }
  72  
  73  /// Abstract type-directed pointer-movement using the MovePtr trait
  74  impl<V:TyVisitor + MovePtr> TyVisitor for MovePtrAdaptor<V> {
  75      fn visit_bot(&mut self) -> bool {
  76          self.align_to::<()>();
  77          if self.inner.visit_bot() { return false; }
  78          self.bump_past::<()>();
  79          true
  80      }
  81  
  82      fn visit_nil(&mut self) -> bool {
  83          self.align_to::<()>();
  84          if self.inner.visit_nil() { return false; }
  85          self.bump_past::<()>();
  86          true
  87      }
  88  
  89      fn visit_bool(&mut self) -> bool {
  90          self.align_to::<bool>();
  91          if self.inner.visit_bool() { return false; }
  92          self.bump_past::<bool>();
  93          true
  94      }
  95  
  96      fn visit_int(&mut self) -> bool {
  97          self.align_to::<int>();
  98          if self.inner.visit_int() { return false; }
  99          self.bump_past::<int>();
 100          true
 101      }
 102  
 103      fn visit_i8(&mut self) -> bool {
 104          self.align_to::<i8>();
 105          if self.inner.visit_i8() { return false; }
 106          self.bump_past::<i8>();
 107          true
 108      }
 109  
 110      fn visit_i16(&mut self) -> bool {
 111          self.align_to::<i16>();
 112          if self.inner.visit_i16() { return false; }
 113          self.bump_past::<i16>();
 114          true
 115      }
 116  
 117      fn visit_i32(&mut self) -> bool {
 118          self.align_to::<i32>();
 119          if self.inner.visit_i32() { return false; }
 120          self.bump_past::<i32>();
 121          true
 122      }
 123  
 124      fn visit_i64(&mut self) -> bool {
 125          self.align_to::<i64>();
 126          if self.inner.visit_i64() { return false; }
 127          self.bump_past::<i64>();
 128          true
 129      }
 130  
 131      fn visit_uint(&mut self) -> bool {
 132          self.align_to::<uint>();
 133          if self.inner.visit_uint() { return false; }
 134          self.bump_past::<uint>();
 135          true
 136      }
 137  
 138      fn visit_u8(&mut self) -> bool {
 139          self.align_to::<u8>();
 140          if self.inner.visit_u8() { return false; }
 141          self.bump_past::<u8>();
 142          true
 143      }
 144  
 145      fn visit_u16(&mut self) -> bool {
 146          self.align_to::<u16>();
 147          if self.inner.visit_u16() { return false; }
 148          self.bump_past::<u16>();
 149          true
 150      }
 151  
 152      fn visit_u32(&mut self) -> bool {
 153          self.align_to::<u32>();
 154          if self.inner.visit_u32() { return false; }
 155          self.bump_past::<u32>();
 156          true
 157      }
 158  
 159      fn visit_u64(&mut self) -> bool {
 160          self.align_to::<u64>();
 161          if self.inner.visit_u64() { return false; }
 162          self.bump_past::<u64>();
 163          true
 164      }
 165  
 166      fn visit_f32(&mut self) -> bool {
 167          self.align_to::<f32>();
 168          if self.inner.visit_f32() { return false; }
 169          self.bump_past::<f32>();
 170          true
 171      }
 172  
 173      fn visit_f64(&mut self) -> bool {
 174          self.align_to::<f64>();
 175          if self.inner.visit_f64() { return false; }
 176          self.bump_past::<f64>();
 177          true
 178      }
 179  
 180      fn visit_f128(&mut self) -> bool {
 181          self.align_to::<f128>();
 182          if self.inner.visit_f128() { return false; }
 183          self.bump_past::<f128>();
 184          true
 185      }
 186  
 187      fn visit_char(&mut self) -> bool {
 188          self.align_to::<char>();
 189          if self.inner.visit_char() { return false; }
 190          self.bump_past::<char>();
 191          true
 192      }
 193  
 194      fn visit_estr_box(&mut self) -> bool {
 195          true
 196      }
 197  
 198      fn visit_estr_uniq(&mut self) -> bool {
 199          self.align_to::<~str>();
 200          if self.inner.visit_estr_uniq() { return false; }
 201          self.bump_past::<~str>();
 202          true
 203      }
 204  
 205      fn visit_estr_slice(&mut self) -> bool {
 206          self.align_to::<&'static str>();
 207          if self.inner.visit_estr_slice() { return false; }
 208          self.bump_past::<&'static str>();
 209          true
 210      }
 211  
 212      fn visit_estr_fixed(&mut self, nuint,
 213                          szuint,
 214                          alignuint) -> bool {
 215          self.align(align);
 216          if self.inner.visit_estr_fixed(n, sz, align) { return false; }
 217          self.bump(sz);
 218          true
 219      }
 220  
 221      fn visit_box(&mut self, mtbluint, inner*TyDesc) -> bool {
 222          self.align_to::<@u8>();
 223          if self.inner.visit_box(mtbl, inner) { return false; }
 224          self.bump_past::<@u8>();
 225          true
 226      }
 227  
 228      fn visit_uniq(&mut self, mtbluint, inner*TyDesc) -> bool {
 229          self.align_to::<Box<u8>>();
 230          if self.inner.visit_uniq(mtbl, inner) { return false; }
 231          self.bump_past::<Box<u8>>();
 232          true
 233      }
 234  
 235      fn visit_ptr(&mut self, mtbluint, inner*TyDesc) -> bool {
 236          self.align_to::<*u8>();
 237          if self.inner.visit_ptr(mtbl, inner) { return false; }
 238          self.bump_past::<*u8>();
 239          true
 240      }
 241  
 242      fn visit_rptr(&mut self, mtbluint, inner*TyDesc) -> bool {
 243          self.align_to::<&'static u8>();
 244          if self.inner.visit_rptr(mtbl, inner) { return false; }
 245          self.bump_past::<&'static u8>();
 246          true
 247      }
 248  
 249      fn visit_evec_box(&mut self, _mtbluint, _inner*TyDesc) -> bool {
 250          true
 251      }
 252  
 253      fn visit_evec_uniq(&mut self, mtbluint, inner*TyDesc) -> bool {
 254          self.align_to::<~[u8]>();
 255          if self.inner.visit_evec_uniq(mtbl, inner) { return false; }
 256          self.bump_past::<~[u8]>();
 257          true
 258      }
 259  
 260      fn visit_evec_slice(&mut self, mtbluint, inner*TyDesc) -> bool {
 261          self.align_to::<&'static [u8]>();
 262          if self.inner.visit_evec_slice(mtbl, inner) { return false; }
 263          self.bump_past::<&'static [u8]>();
 264          true
 265      }
 266  
 267      fn visit_evec_fixed(&mut self, nuint, szuint, alignuint,
 268                          mtbluint, inner*TyDesc) -> bool {
 269          self.align(align);
 270          if self.inner.visit_evec_fixed(n, sz, align, mtbl, inner) {
 271              return false;
 272          }
 273          self.bump(sz);
 274          true
 275      }
 276  
 277      fn visit_enter_rec(&mut self, n_fieldsuint, szuint, alignuint) -> bool {
 278          self.align(align);
 279          if self.inner.visit_enter_rec(n_fields, sz, align) { return false; }
 280          true
 281      }
 282  
 283      fn visit_rec_field(&mut self, iuint, name&str,
 284                         mtbluint, inner*TyDesc) -> bool {
 285          unsafe { self.align((*inner).align); }
 286          if self.inner.visit_rec_field(i, name, mtbl, inner) {
 287              return false;
 288          }
 289          unsafe { self.bump((*inner).size); }
 290          true
 291      }
 292  
 293      fn visit_leave_rec(&mut self, n_fieldsuint, szuint, alignuint) -> bool {
 294          if self.inner.visit_leave_rec(n_fields, sz, align) { return false; }
 295          true
 296      }
 297  
 298      fn visit_enter_class(&mut self, name&str, named_fieldsbool, n_fieldsuint, szuint,
 299                           alignuint) -> bool {
 300          self.align(align);
 301          if self.inner.visit_enter_class(name, named_fields, n_fields, sz, align) {
 302              return false;
 303          }
 304          true
 305      }
 306  
 307      fn visit_class_field(&mut self, iuint, name&str, namedbool, mtbluint,
 308                           inner*TyDesc) -> bool {
 309          unsafe { self.align((*inner).align); }
 310          if self.inner.visit_class_field(i, name, named, mtbl, inner) {
 311              return false;
 312          }
 313          unsafe { self.bump((*inner).size); }
 314          true
 315      }
 316  
 317      fn visit_leave_class(&mut self, name&str, named_fieldsbool, n_fieldsuint, szuint,
 318                           alignuint) -> bool {
 319          if self.inner.visit_leave_class(name, named_fields, n_fields, sz, align) {
 320              return false;
 321          }
 322          true
 323      }
 324  
 325      fn visit_enter_tup(&mut self, n_fieldsuint, szuint, alignuint) -> bool {
 326          self.align(align);
 327          if self.inner.visit_enter_tup(n_fields, sz, align) { return false; }
 328          true
 329      }
 330  
 331      fn visit_tup_field(&mut self, iuint, inner*TyDesc) -> bool {
 332          unsafe { self.align((*inner).align); }
 333          if self.inner.visit_tup_field(i, inner) { return false; }
 334          unsafe { self.bump((*inner).size); }
 335          true
 336      }
 337  
 338      fn visit_leave_tup(&mut self, n_fieldsuint, szuint, alignuint) -> bool {
 339          if self.inner.visit_leave_tup(n_fields, sz, align) { return false; }
 340          true
 341      }
 342  
 343      fn visit_enter_fn(&mut self, purityuint, protouint,
 344                        n_inputsuint, retstyleuint) -> bool {
 345          if self.inner.visit_enter_fn(purity, proto, n_inputs, retstyle) {
 346              return false
 347          }
 348          true
 349      }
 350  
 351      fn visit_fn_input(&mut self, iuint, modeuint, inner*TyDesc) -> bool {
 352          if self.inner.visit_fn_input(i, mode, inner) { return false; }
 353          true
 354      }
 355  
 356      fn visit_fn_output(&mut self, retstyleuint, variadicbool, inner*TyDesc) -> bool {
 357          if self.inner.visit_fn_output(retstyle, variadic, inner) { return false; }
 358          true
 359      }
 360  
 361      fn visit_leave_fn(&mut self, purityuint, protouint,
 362                        n_inputsuint, retstyleuint) -> bool {
 363          if self.inner.visit_leave_fn(purity, proto, n_inputs, retstyle) {
 364              return false;
 365          }
 366          true
 367      }
 368  
 369      fn visit_enter_enum(&mut self, n_variantsuint,
 370                          get_disrextern unsafe fn(ptr: *Opaque) -> Disr,
 371                          szuint, alignuint)
 372                       -> bool {
 373          self.align(align);
 374          if self.inner.visit_enter_enum(n_variants, get_disr, sz, align) {
 375              return false;
 376          }
 377          true
 378      }
 379  
 380      fn visit_enter_enum_variant(&mut self, variantuint,
 381                                  disr_valDisr,
 382                                  n_fieldsuint,
 383                                  name&str) -> bool {
 384          if self.inner.visit_enter_enum_variant(variant, disr_val,
 385                                                   n_fields, name) {
 386              return false;
 387          }
 388          true
 389      }
 390  
 391      fn visit_enum_variant_field(&mut self, iuint, offsetuint, inner*TyDesc) -> bool {
 392          self.inner.push_ptr();
 393          self.bump(offset);
 394          if self.inner.visit_enum_variant_field(i, offset, inner) { return false; }
 395          self.inner.pop_ptr();
 396          true
 397      }
 398  
 399      fn visit_leave_enum_variant(&mut self, variantuint,
 400                                  disr_valDisr,
 401                                  n_fieldsuint,
 402                                  name&str) -> bool {
 403          if self.inner.visit_leave_enum_variant(variant, disr_val,
 404                                                   n_fields, name) {
 405              return false;
 406          }
 407          true
 408      }
 409  
 410      fn visit_leave_enum(&mut self, n_variantsuint,
 411                          get_disrextern unsafe fn(ptr: *Opaque) -> Disr,
 412                          szuint, alignuint) -> bool {
 413          if self.inner.visit_leave_enum(n_variants, get_disr, sz, align) {
 414              return false;
 415          }
 416          self.bump(sz);
 417          true
 418      }
 419  
 420      fn visit_trait(&mut self, name&str) -> bool {
 421          self.align_to::<Box<TyVisitor>>();
 422          if self.inner.visit_trait(name) { return false; }
 423          self.bump_past::<Box<TyVisitor>>();
 424          true
 425      }
 426  
 427      fn visit_param(&mut self, iuint) -> bool {
 428          if self.inner.visit_param(i) { return false; }
 429          true
 430      }
 431  
 432      fn visit_self(&mut self) -> bool {
 433          self.align_to::<&'static u8>();
 434          if self.inner.visit_self() { return false; }
 435          self.align_to::<&'static u8>();
 436          true
 437      }
 438  }


libstd/reflect.rs:41:58-41:58 -struct- definition:
/// Adaptor to wrap around visitors implementing MovePtr.
pub struct MovePtrAdaptor<V> {
    inner: V
references:- 4
44: }
45: pub fn MovePtrAdaptor<V:TyVisitor + MovePtr>(v: V) -> MovePtrAdaptor<V> {
46:     MovePtrAdaptor { inner: v }
--
73: /// Abstract type-directed pointer-movement using the MovePtr trait
74: impl<V:TyVisitor + MovePtr> TyVisitor for MovePtrAdaptor<V> {
75:     fn visit_bot(&mut self) -> bool {


libstd/reflect.rs:44:2-44:2 -fn- definition:
}
pub fn MovePtrAdaptor<V:TyVisitor + MovePtr>(v: V) -> MovePtrAdaptor<V> {
    MovePtrAdaptor { inner: v }
references:- 2
libstd/repr.rs:
162:             };
163:             let mut v = reflect::MovePtrAdaptor(u);
164:             // Obviously this should not be a thing, but blame #8401 for now
--
597:         let u = ReprVisitor(ptr, writer);
598:         let mut v = reflect::MovePtrAdaptor(u);
599:         visit_tydesc(tydesc, &mut v as &mut TyVisitor);


libstd/reflect.rs:28:4-28:4 -trait- definition:
 */
pub trait MovePtr {
    fn move_ptr(&mut self, adjustment: |*u8| -> *u8);
references:- 4
73: /// Abstract type-directed pointer-movement using the MovePtr trait
74: impl<V:TyVisitor + MovePtr> TyVisitor for MovePtrAdaptor<V> {
75:     fn visit_bot(&mut self) -> bool {
libstd/repr.rs:
123: impl<'a> MovePtr for ReprVisitor<'a> {
124:     #[inline]
libstd/reflect.rs:
49: impl<V:TyVisitor + MovePtr> MovePtrAdaptor<V> {
50:     #[inline]


libstd/reflect.rs:36:10-36:10 -fn- definition:
pub fn align(size: uint, align: uint) -> uint {
    ((size + align) - 1u) & !(align - 1u)
}
references:- 2
libstd/repr.rs:
218:             self.visit_ptr_inner(p as *u8, inner);
219:             p = align(unsafe { p.offset(sz as int) as uint }, al) as *u8;
220:             left -= dec;
libstd/reflect.rs:
56:     pub fn align(&mut self, a: uint) {
57:         self.inner.move_ptr(|p| align(p as uint, a) as *u8)
58:     }