From eb7e9dce4d58953d832b33897afd07307997fc51 Mon Sep 17 00:00:00 2001 From: Patrick Walton Date: Mon, 8 Aug 2011 14:26:58 -0700 Subject: rt: Stub the shape-based cmp upcall --- src/rt/rust_shape.cpp | 129 ++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 120 insertions(+), 9 deletions(-) (limited to 'src/rt/rust_shape.cpp') 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 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 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 - class data { typedef data_pair t; }; + struct data { typedef data_pair 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 +inline data_pair +bump_dp(ptr_pair &ptr) { + data_pair data(*reinterpret_cast(ptr.fst), + *reinterpret_cast(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 ctxt(const ctxt &other, const uint8_t *in_sp = NULL, @@ -665,7 +702,7 @@ public: template static size_align get(const ctxt &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 > { 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 >(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(this)->walk_res(align, dtor, n_ty_params, + ty_params_sp); + } + void walk_var(bool align, uint8_t param_index) { static_cast(this)->walk_var(align, param_index); } template - void walk_number(bool align) { DATA_SIMPLE(W, walk_number(align)); } + void walk_number(bool align) { DATA_SIMPLE(W, walk_number()); } }; template @@ -825,12 +876,12 @@ data::walk_ivec(bool align, bool is_pod, size_align &elem_sa) { template void data::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::t tag_variant; if (tinfo.variant_count > 1) @@ -846,7 +897,7 @@ data::walk_tag(bool align, tag_info &tinfo) { #if 0 -class copy : public data { +class copy : public data { // TODO }; @@ -856,7 +907,67 @@ class copy : public data { // Structural comparison glue. class cmp : public data { +private: + template + 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(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 &tag_variants); + void walk_res(bool align, const rust_fn *dtor, uint16_t n_ty_params, + const uint8_t *ty_params_sp); + + template + void walk_number() { result = cmp_number(dp); } }; +void +cmp::walk_tag(bool align, tag_info &tinfo, + data_pair &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 +int +cmp::cmp_number(ptr_pair &ptrs) { + T a = *(reinterpret_cast(dp.fst)); + T b = *(reinterpret_cast(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; + } +} + -- cgit 1.4.1-3-g733a5