about summary refs log tree commit diff
path: root/src/rt/rust_shape.cpp
diff options
context:
space:
mode:
authorPatrick Walton <pcwalton@mimiga.net>2011-08-08 14:26:58 -0700
committerPatrick Walton <pcwalton@mimiga.net>2011-08-08 14:33:06 -0700
commiteb7e9dce4d58953d832b33897afd07307997fc51 (patch)
treecf6015a274cb77eef6e2345aaab1250e37c86d29 /src/rt/rust_shape.cpp
parentd4a4224d1b08e306a2abc0db5e1408456f9f5e66 (diff)
downloadrust-eb7e9dce4d58953d832b33897afd07307997fc51.tar.gz
rust-eb7e9dce4d58953d832b33897afd07307997fc51.zip
rt: Stub the shape-based cmp upcall
Diffstat (limited to 'src/rt/rust_shape.cpp')
-rw-r--r--src/rt/rust_shape.cpp129
1 files changed, 120 insertions, 9 deletions
diff --git a/src/rt/rust_shape.cpp b/src/rt/rust_shape.cpp
index 594c3138331..daa649cc621 100644
--- a/src/rt/rust_shape.cpp
+++ b/src/rt/rust_shape.cpp
@@ -69,7 +69,7 @@ const uint8_t CMP_LE = 2u;
 // of two.
 template<typename T>
 static inline T
-round_up(T size, size_t alignment) {
+align_to(T size, size_t alignment) {
     assert(alignment);
     T x = (T)(((uintptr_t)size + alignment - 1) & ~(alignment - 1));
     return x;
@@ -133,10 +133,17 @@ struct tag_info {
     const type_param *params;               // Array of type parameters.
 };
 
+
+// Pointer pairs for structural comparison
+
 template<typename T>
 class data_pair {
 public:
     T fst, snd;
+
+    data_pair() {}
+    data_pair(T &in_fst, T &in_snd) : fst(in_fst), snd(in_snd) {}
+
     inline void operator=(const T rhs) { fst = snd = rhs; }
 };
 
@@ -145,7 +152,7 @@ public:
     uint8_t *fst, *snd;
 
     template<typename T>
-    class data { typedef data_pair<T> t; };
+    struct data { typedef data_pair<T> t; };
 
     ptr_pair(uint8_t *in_fst, uint8_t *in_snd) : fst(in_fst), snd(in_snd) {}
 
@@ -155,12 +162,36 @@ public:
         return make(fst + n, snd + n);
     }
 
+    inline ptr_pair operator+=(size_t n) {
+        fst += n; snd += n;
+        return *this;
+    }
+
+    inline ptr_pair operator-(size_t n) const {
+        return make(fst - n, snd - n);
+    }
+
     static inline ptr_pair make(uint8_t *fst, uint8_t *snd) {
         ptr_pair self(fst, snd);
         return self;
     }
 };
 
+inline ptr_pair
+align_to(const ptr_pair const &pair, size_t n) {
+    return ptr_pair::make(align_to(pair.fst, n), align_to(pair.snd, n));
+}
+
+// NB: This function does not align.
+template<typename T>
+inline data_pair<T>
+bump_dp(ptr_pair &ptr) {
+    data_pair<T> data(*reinterpret_cast<T *>(ptr.fst),
+                      *reinterpret_cast<T *>(ptr.snd));
+    ptr += sizeof(T);
+    return data;
+}
+
 
 // Contexts
 
@@ -174,6 +205,12 @@ public:
     const rust_shape_tables *tables;
     rust_task *task;
 
+    ctxt(rust_task *in_task,
+         const uint8_t *in_sp,
+         const type_param *in_params,
+         const rust_shape_tables *in_tables)
+    : sp(in_sp), params(in_params), tables(in_tables), task(in_task) {}
+
     template<typename U>
     ctxt(const ctxt<U> &other,
          const uint8_t *in_sp = NULL,
@@ -665,7 +702,7 @@ public:
 
     template<typename T>
     static size_align get(const ctxt<T> &other_cx, unsigned back_up = 0) {
-        size_of cx(other_cx, other_cx->sp - back_up);
+        size_of cx(other_cx, other_cx.sp - back_up);
         cx.walk(false);
         assert(cx.sa.alignment > 0);
         return cx.sa;
@@ -696,7 +733,7 @@ size_of::compute_tag_size(tag_info &tinfo) {
         bool first = true;
         while (sub.sp != variant_end) {
             if (!first)
-                variant_sa.size = round_up(variant_sa.size, sub.sa.alignment);
+                variant_sa.size = align_to(variant_sa.size, sub.sa.alignment);
             sub.walk(!first);
             first = false;
 
@@ -729,7 +766,7 @@ size_of::walk_struct(bool align, const uint8_t *end_sp) {
     bool first = true;
     while (sp != end_sp) {
         if (!first)
-            struct_sa.size = round_up(struct_sa.size, sa.alignment);
+            struct_sa.size = align_to(struct_sa.size, sa.alignment);
         walk(!first);
         first = false;
 
@@ -764,6 +801,13 @@ class data : public ctxt< data<T,U> > {
 public:
     U dp;
 
+    data(rust_task *in_task,
+         const uint8_t *in_sp,
+         const type_param *in_params,
+         const rust_shape_tables *in_tables,
+         U const &in_dp)
+    : ctxt< data<T,U> >(in_task, in_sp, in_params, in_tables), dp(in_dp) {}
+
     void walk_tag(bool align, tag_info &tinfo);
     void walk_ivec(bool align, bool is_pod, size_align &elem_sa);
 
@@ -796,12 +840,19 @@ public:
         dp += sizeof(void *) * 2;
     }
 
+    void walk_res(bool align, const rust_fn *dtor, uint16_t n_ty_params,
+                  const uint8_t *ty_params_sp) {
+        // Delegate to the implementation.
+        static_cast<T *>(this)->walk_res(align, dtor, n_ty_params,
+                                         ty_params_sp);
+    }
+
     void walk_var(bool align, uint8_t param_index) {
         static_cast<T *>(this)->walk_var(align, param_index);
     }
 
     template<typename W>
-    void walk_number(bool align) { DATA_SIMPLE(W, walk_number<W>(align)); }
+    void walk_number(bool align) { DATA_SIMPLE(W, walk_number<W>()); }
 };
 
 template<typename T,typename U>
@@ -825,12 +876,12 @@ data<T,U>::walk_ivec(bool align, bool is_pod, size_align &elem_sa) {
 template<typename T,typename U>
 void
 data<T,U>::walk_tag(bool align, tag_info &tinfo) {
-    size_of::compute_tag_size(tinfo);
+    size_of::compute_tag_size(*this, tinfo);
 
     if (tinfo.variant_count > 1 && align)
         dp = align_to(dp, ALIGNOF(uint32_t));
 
-    U end_dp = tinfo.tag_sa.size;
+    U end_dp = dp + tinfo.tag_sa.size;
 
     typename U::template data<uint32_t>::t tag_variant;
     if (tinfo.variant_count > 1)
@@ -846,7 +897,7 @@ data<T,U>::walk_tag(bool align, tag_info &tinfo) {
 
 #if 0
 
-class copy : public data<copy> {
+class copy : public data<copy,uint8_t *> {
     // TODO
 };
 
@@ -856,7 +907,67 @@ class copy : public data<copy> {
 // Structural comparison glue.
 
 class cmp : public data<cmp,ptr_pair> {
+private:
+    template<typename T>
+    int cmp_number(ptr_pair &ptrs);
+
+public:
+    int result;
+
+    cmp(rust_task *in_task,
+        const uint8_t *in_sp,
+        const type_param *in_params,
+        const rust_shape_tables *in_tables,
+        uint8_t *in_data_0,
+        uint8_t *in_data_1)
+    : data<cmp,ptr_pair>(in_task, in_sp, in_params, in_tables,
+                         ptr_pair::make(in_data_0, in_data_1)) {}
+
+    void walk_tag(bool align, tag_info &tinfo,
+                  data_pair<uint32_t> &tag_variants);
+    void walk_res(bool align, const rust_fn *dtor, uint16_t n_ty_params,
+                  const uint8_t *ty_params_sp);
+
+    template<typename T>
+    void walk_number() { result = cmp_number<T>(dp); }
 };
 
+void
+cmp::walk_tag(bool align, tag_info &tinfo,
+              data_pair<uint32_t> &tag_variants) {
+    abort();    // TODO
+}
+
+void
+cmp::walk_res(bool align, const rust_fn *dtor, uint16_t n_ty_params,
+              const uint8_t *ty_params_sp) {
+    abort();    // TODO
+}
+
+template<typename T>
+int
+cmp::cmp_number(ptr_pair &ptrs) {
+    T a = *(reinterpret_cast<T *>(dp.fst));
+    T b = *(reinterpret_cast<T *>(dp.snd));
+    return (a < b) ? -1 : (a == b) ? 0 : 1;
+}
+
 } // end namespace shape
 
+extern "C" void
+upcall_cmp_type(int8_t *result, rust_task *task, type_desc *tydesc,
+                const type_desc **subtydescs, uint8_t *data_0,
+                uint8_t *data_1, uint8_t cmp_type) {
+    shape::arena arena;
+    shape::type_param *params = shape::type_param::make(tydesc, arena);
+    shape::cmp cmp(task, tydesc->shape, params, tydesc->shape_tables, data_0,
+                   data_1);
+    cmp.walk(true);
+
+    switch (cmp_type) {
+    case shape::CMP_EQ: *result = cmp.result == 0;  break;
+    case shape::CMP_LT: *result = cmp.result < 0;   break;
+    case shape::CMP_LE: *result = cmp.result <= 0;  break;
+    }
+}
+