about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMarijn Haverbeke <marijnh@gmail.com>2012-01-11 09:44:27 +0100
committerMarijn Haverbeke <marijnh@gmail.com>2012-01-11 11:46:44 +0100
commit87253cf3a91994aac5a9e679ae17cfcad1ed0fcf (patch)
treef59d0eebc135a86b4f2a84e9712898d98c3b9dbd
parent0145b15f0cd61389599eb1cb77c028f7f4a8229a (diff)
downloadrust-87253cf3a91994aac5a9e679ae17cfcad1ed0fcf.tar.gz
rust-87253cf3a91994aac5a9e679ae17cfcad1ed0fcf.zip
Revert some iface shape code, fix a few more things in it
We can now run the compiler with an iface-based hashtable
implementation.
-rw-r--r--src/rt/rust_cc.cpp5
-rw-r--r--src/rt/rust_internal.h17
-rw-r--r--src/rt/rust_shape.h27
3 files changed, 19 insertions, 30 deletions
diff --git a/src/rt/rust_cc.cpp b/src/rt/rust_cc.cpp
index a96c3739ca3..d04ae2e09df 100644
--- a/src/rt/rust_cc.cpp
+++ b/src/rt/rust_cc.cpp
@@ -111,8 +111,7 @@ class irc : public shape::data<irc,shape::ptr> {
     }
 
     void walk_iface() {
-        // an iface is always a ptr to a ref-counted obj.
-        shape::data<irc,shape::ptr>::walk_box_contents();
+        shape::data<irc,shape::ptr>::walk_iface_contents(dp);
     }
 
     void walk_res(const shape::rust_fn *dtor, unsigned n_params,
@@ -503,7 +502,7 @@ class sweep : public shape::data<sweep,shape::ptr> {
     }
 
     void walk_iface() {
-        shape::data<sweep,shape::ptr>::walk_box_contents();
+        shape::data<sweep,shape::ptr>::walk_iface_contents(dp);
     }
 
     void walk_res(const shape::rust_fn *dtor, unsigned n_params,
diff --git a/src/rt/rust_internal.h b/src/rt/rust_internal.h
index f9300cad443..b83d74f6bfe 100644
--- a/src/rt/rust_internal.h
+++ b/src/rt/rust_internal.h
@@ -260,23 +260,6 @@ struct rust_opaque_closure;
 //   no arguments (and hence the final void*) is harmless
 typedef void (*CDECL spawn_fn)(void*, rust_opaque_closure*, void *);
 
-// corresponds to the layout of an iface value
-//
-// Note: eventually, we should inline the contents of opaque_iface_contents
-// into opaque_iface in the LLVM code.  Otherwise, the alignment of
-// opaque_iface_contents depends on the opaque data!
-
-struct opaque_iface_contents {
-    const type_desc *td; // describes opaque_iface_contents
-    const void *vtable;
-    // (opaque data goes here)
-};
-
-struct opaque_iface {
-    intptr_t ref_count;
-    opaque_iface_contents contents;
-};
-
 // corresponds to the layout of a fn(), fn@(), fn~() etc
 struct fn_env_pair {
     spawn_fn f;
diff --git a/src/rt/rust_shape.h b/src/rt/rust_shape.h
index ca8cd2c88a5..0def948223f 100644
--- a/src/rt/rust_shape.h
+++ b/src/rt/rust_shape.h
@@ -363,7 +363,7 @@ public:
 template<typename T>
 void
 ctxt<T>::walk() {
-    switch (*sp++) {
+  switch (*sp++) {
     case SHAPE_U8:      WALK_NUMBER(uint8_t);   break;
     case SHAPE_U16:     WALK_NUMBER(uint16_t);  break;
     case SHAPE_U32:     WALK_NUMBER(uint32_t);  break;
@@ -823,7 +823,7 @@ protected:
     void walk_uniq_contents();
     void walk_fn_contents(ptr &dp);
     void walk_obj_contents(ptr &dp);
-    void walk_iface_value(ptr &dp);
+    void walk_iface_contents(ptr &dp);
     void walk_variant(tag_info &tinfo, tag_variant_t variant);
 
     static std::pair<uint8_t *,uint8_t *> get_vec_data_range(ptr dp);
@@ -870,7 +870,7 @@ public:
 
     void walk_iface() {
         ALIGN_TO(alignof<void *>());
-        U next_dp = dp + sizeof(void *) * 2;
+        U next_dp = dp + sizeof(void *);
         static_cast<T *>(this)->walk_iface();
         dp = next_dp;
     }
@@ -1003,14 +1003,21 @@ data<T,U>::walk_obj_contents(ptr &dp) {
 
 template<typename T,typename U>
 void
-data<T,U>::walk_iface_value(ptr &dp) {
-    opaque_iface *box_ptr = bump_dp<opaque_iface *>(dp);
+data<T,U>::walk_iface_contents(ptr &dp) {
+    uint8_t *box_ptr = bump_dp<uint8_t *>(dp);
     if (!box_ptr) return;
-    const type_desc *contents_td = box_ptr->contents.td;
-    ptr contents_dp((uintptr_t)&box_ptr->contents);
-    T sub(*static_cast<T *>(this), contents_td->shape, NULL, NULL, contents_dp);
+    U ref_count_dp(box_ptr);
+    uint8_t *body_ptr = box_ptr + sizeof(void*);
+    type_desc *valtydesc =
+        *reinterpret_cast<type_desc **>(body_ptr);
+    ptr value_dp(body_ptr + sizeof(void*) * 2);
+    // FIXME The 5 is a hard-coded way to skip over a struct shape
+    // header and the first two (number-typed) fields. This is too
+    // fragile, but I didn't see a good way to properly encode it.
+    T sub(*static_cast<T *>(this), valtydesc->shape + 5, NULL, NULL,
+          value_dp);
     sub.align = true;
-    sub.walk();
+    static_cast<T *>(this)->walk_box_contents(sub, ref_count_dp);
 }
 
 // Polymorphic logging, for convenience
@@ -1099,7 +1106,7 @@ private:
     void walk_iface() {
         out << prefix << "iface(";
         prefix = "";
-        data<log,ptr>::walk_iface_value(dp);
+        data<log,ptr>::walk_iface_contents(dp);
         out << prefix << ")";
     }