about summary refs log tree commit diff
diff options
context:
space:
mode:
authorJed Davis <jld@panix.com>2013-04-06 14:01:56 -0700
committerJed Davis <jld@panix.com>2013-04-08 01:03:42 -0700
commit0ca1885da133cb7e4a1f4d557cfde5d16ac68231 (patch)
tree5701106cf7a6fa8b06a2d4bd9752237fedd90b0b
parent44d4d6de762f3f9aae1fedcf454c66b79b3ad58d (diff)
downloadrust-0ca1885da133cb7e4a1f4d557cfde5d16ac68231.tar.gz
rust-0ca1885da133cb7e4a1f4d557cfde5d16ac68231.zip
Feed enum field offsets to type vistors.
-rw-r--r--src/libcore/reflect.rs14
-rw-r--r--src/libcore/repr.rs27
-rw-r--r--src/librustc/front/intrinsic.rs2
-rw-r--r--src/librustc/middle/trans/reflect.rs32
-rw-r--r--src/test/run-pass/reflect-visit-data.rs6
5 files changed, 61 insertions, 20 deletions
diff --git a/src/libcore/reflect.rs b/src/libcore/reflect.rs
index a449c4e73cf..a38e51b3813 100644
--- a/src/libcore/reflect.rs
+++ b/src/libcore/reflect.rs
@@ -406,7 +406,7 @@ impl<V:TyVisitor + MovePtr> TyVisitor for MovePtrAdaptor<V> {
                                 disr_val: int,
                                 n_fields: uint,
                                 name: &str) -> bool {
-        self.inner.push_ptr();
+        self.inner.push_ptr(); // NOTE remove after next snapshot
         if ! self.inner.visit_enter_enum_variant(variant, disr_val,
                                                  n_fields, name) {
             return false;
@@ -414,6 +414,7 @@ impl<V:TyVisitor + MovePtr> TyVisitor for MovePtrAdaptor<V> {
         true
     }
 
+    #[cfg(stage0)]
     fn visit_enum_variant_field(&self, i: uint, inner: *TyDesc) -> bool {
         unsafe { self.align((*inner).align); }
         if ! self.inner.visit_enum_variant_field(i, inner) { return false; }
@@ -421,6 +422,15 @@ impl<V:TyVisitor + MovePtr> TyVisitor for MovePtrAdaptor<V> {
         true
     }
 
+    #[cfg(not(stage0))]
+    fn visit_enum_variant_field(&self, i: uint, offset: uint, inner: *TyDesc) -> bool {
+        self.inner.push_ptr();
+        self.bump(offset);
+        if ! self.inner.visit_enum_variant_field(i, offset, inner) { return false; }
+        self.inner.pop_ptr();
+        true
+    }
+
     fn visit_leave_enum_variant(&self, variant: uint,
                                 disr_val: int,
                                 n_fields: uint,
@@ -429,7 +439,7 @@ impl<V:TyVisitor + MovePtr> TyVisitor for MovePtrAdaptor<V> {
                                                  n_fields, name) {
             return false;
         }
-        self.inner.pop_ptr();
+        self.inner.pop_ptr(); // NOTE remove after next snapshot
         true
     }
 
diff --git a/src/libcore/repr.rs b/src/libcore/repr.rs
index a51f874f371..3d42f064831 100644
--- a/src/libcore/repr.rs
+++ b/src/libcore/repr.rs
@@ -193,6 +193,14 @@ pub impl ReprVisitor {
         self.bump(sys::size_of::<T>());
     }
 
+    #[cfg(stage0)] #[inline(always)]
+    fn stage0_bump_past<T>(&self) {
+        self.bump_past::<T>();
+    }
+    #[cfg(not(stage0))] #[inline(always)]
+    fn stage0_bump_past<T>(&self) {
+    }
+
     #[inline(always)]
     fn visit_inner(&self, inner: *TyDesc) -> bool {
         self.visit_ptr_inner(self.ptr, inner)
@@ -487,7 +495,7 @@ impl TyVisitor for ReprVisitor {
                         self.var_stk.push(TagMismatch);
                     }
                 };
-                self.bump_past::<int>();
+                self.stage0_bump_past::<int>();
             }
         }
 
@@ -500,6 +508,7 @@ impl TyVisitor for ReprVisitor {
         true
     }
 
+    #[cfg(stage0)]
     fn visit_enum_variant_field(&self, i: uint, inner: *TyDesc) -> bool {
         match self.var_stk[vec::uniq_len(&const self.var_stk) - 1] {
             Degenerate | TagMatch => {
@@ -515,6 +524,22 @@ impl TyVisitor for ReprVisitor {
         true
     }
 
+    #[cfg(not(stage0))]
+    fn visit_enum_variant_field(&self, i: uint, _offset: uint, inner: *TyDesc) -> bool {
+        match self.var_stk[vec::uniq_len(&const self.var_stk) - 1] {
+            Degenerate | TagMatch => {
+                if i != 0 {
+                    self.writer.write_str(", ");
+                }
+                if ! self.visit_inner(inner) {
+                    return false;
+                }
+            }
+            TagMismatch => ()
+        }
+        true
+    }
+
     fn visit_leave_enum_variant(&self, _variant: uint,
                                 _disr_val: int,
                                 n_fields: uint,
diff --git a/src/librustc/front/intrinsic.rs b/src/librustc/front/intrinsic.rs
index 7d5177a6dfb..7a07ce12516 100644
--- a/src/librustc/front/intrinsic.rs
+++ b/src/librustc/front/intrinsic.rs
@@ -96,7 +96,7 @@ pub mod intrinsic {
                                     disr_val: int,
                                     n_fields: uint,
                                     name: &str) -> bool;
-        fn visit_enum_variant_field(&self, i: uint, inner: *TyDesc) -> 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,
diff --git a/src/librustc/middle/trans/reflect.rs b/src/librustc/middle/trans/reflect.rs
index 224981d6e75..9d62231905e 100644
--- a/src/librustc/middle/trans/reflect.rs
+++ b/src/librustc/middle/trans/reflect.rs
@@ -10,6 +10,7 @@
 
 
 use lib::llvm::{TypeRef, ValueRef};
+use middle::trans::adt;
 use middle::trans::base::*;
 use middle::trans::build::*;
 use middle::trans::callee::{ArgVals, DontAutorefArg};
@@ -266,23 +267,28 @@ pub impl Reflector {
           // variant?
           ty::ty_enum(did, ref substs) => {
             let bcx = self.bcx;
-            let tcx = bcx.ccx().tcx;
-            let variants = ty::substd_enum_variants(tcx, did, substs);
+            let ccx = bcx.ccx();
+            let repr = adt::represent_type(bcx.ccx(), t);
+            let variants = ty::substd_enum_variants(ccx.tcx, did, substs);
 
-            let extra = ~[self.c_uint(vec::len(variants))]
+            let enum_args = ~[self.c_uint(vec::len(variants))]
                 + self.c_size_and_align(t);
-            do self.bracketed(~"enum", extra) |this| {
+            do self.bracketed(~"enum", enum_args) |this| {
                 for variants.eachi |i, v| {
-                    let extra1 = ~[this.c_uint(i),
-                                   this.c_int(v.disr_val),
-                                   this.c_uint(vec::len(v.args)),
-                                   this.c_slice(
-                                       bcx.ccx().sess.str_of(v.name))];
-                    do this.bracketed(~"enum_variant", extra1) |this| {
+                    let variant_args = ~[this.c_uint(i),
+                                         this.c_int(v.disr_val),
+                                         this.c_uint(vec::len(v.args)),
+                                         this.c_slice(ccx.sess.str_of(v.name))];
+                    do this.bracketed(~"enum_variant", variant_args) |this| {
                         for v.args.eachi |j, a| {
-                            let extra = ~[this.c_uint(j),
-                                          this.c_tydesc(*a)];
-                            this.visit(~"enum_variant_field", extra);
+                            let bcx = this.bcx;
+                            let null = C_null(T_ptr(type_of(ccx, t)));
+                            let offset = p2i(ccx, adt::trans_field_ptr(bcx, repr, null,
+                                                                       v.disr_val, j));
+                            let field_args = ~[this.c_uint(j),
+                                               offset,
+                                               this.c_tydesc(*a)];
+                            this.visit(~"enum_variant_field", field_args);
                         }
                     }
                 }
diff --git a/src/test/run-pass/reflect-visit-data.rs b/src/test/run-pass/reflect-visit-data.rs
index a27599e6ed0..8ddc845f50c 100644
--- a/src/test/run-pass/reflect-visit-data.rs
+++ b/src/test/run-pass/reflect-visit-data.rs
@@ -394,8 +394,8 @@ impl<V:TyVisitor + movable_ptr> TyVisitor for ptr_visit_adaptor<V> {
         true
     }
 
-    fn visit_enum_variant_field(&self, i: uint, inner: *TyDesc) -> bool {
-        if ! self.inner.visit_enum_variant_field(i, inner) { return false; }
+    fn visit_enum_variant_field(&self, i: uint, offset: uint, inner: *TyDesc) -> bool {
+        if ! self.inner.visit_enum_variant_field(i, offset, inner) { return false; }
         true
     }
 
@@ -594,7 +594,7 @@ impl TyVisitor for my_visitor {
                                 _disr_val: int,
                                 _n_fields: uint,
                                 _name: &str) -> bool { true }
-    fn visit_enum_variant_field(&self, _i: uint, inner: *TyDesc) -> bool {
+    fn visit_enum_variant_field(&self, _i: uint, _offset: uint, inner: *TyDesc) -> bool {
         self.visit_inner(inner)
     }
     fn visit_leave_enum_variant(&self, _variant: uint,