From 7d7f62613a49c03851fcde9fddb14ec6b474c50f Mon Sep 17 00:00:00 2001 From: Patrick Walton Date: Mon, 8 Aug 2011 18:29:20 -0700 Subject: rt: Compare tags --- src/rt/rust_shape.cpp | 66 +++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 59 insertions(+), 7 deletions(-) (limited to 'src/rt/rust_shape.cpp') diff --git a/src/rt/rust_shape.cpp b/src/rt/rust_shape.cpp index dfc4d20f496..28de981b320 100644 --- a/src/rt/rust_shape.cpp +++ b/src/rt/rust_shape.cpp @@ -228,6 +228,9 @@ public: void walk(bool align); + std::pair + get_variant_sp(tag_info &info, uint32_t variant_id); + protected: static inline uint16_t get_u16(const uint8_t *addr); static inline uint16_t get_u16_bump(const uint8_t *&addr); @@ -390,6 +393,19 @@ ctxt::get_size_align(const uint8_t *&addr) { return result; } +// Returns a pointer to the beginning and a pointer to the end of the shape of +// the tag variant with the given ID. +template +std::pair +ctxt::get_variant_sp(tag_info &tinfo, uint32_t variant_id) { + uint16_t variant_offset = get_u16(tinfo.info_ptr + + variant_id * sizeof(uint16_t)); + const uint8_t *variant_ptr = tables->tags + variant_offset; + uint16_t variant_len = get_u16_bump(variant_ptr); + const uint8_t *variant_end = variant_ptr + variant_len; + return std::make_pair(variant_ptr, variant_end); +} + template void ctxt::walk_evec(bool align) { @@ -724,12 +740,10 @@ size_of::compute_tag_size(tag_info &tinfo) { tinfo.tag_sa.set(0, 0); for (uint16_t i = 0; i < n_largest_variants; i++) { uint16_t variant_id = get_u16_bump(tinfo.largest_variants_ptr); - uint16_t variant_offset = get_u16(tinfo.info_ptr + - variant_id * sizeof(uint16_t)); - const uint8_t *variant_ptr = tables->tags + variant_offset; - - uint16_t variant_len = get_u16_bump(variant_ptr); - const uint8_t *variant_end = variant_ptr + variant_len; + std::pair variant_ptr_and_end = + get_variant_sp(tinfo, variant_id); + const uint8_t *variant_ptr = variant_ptr_and_end.first; + const uint8_t *variant_end = variant_ptr_and_end.second; size_of sub(*this, variant_ptr, params, NULL); @@ -852,6 +866,9 @@ public: static_cast(this)->walk_var(align, param_index); } + // Called by derived classes only. + void walk_variant(bool align, tag_info &tinfo, uint32_t variant); + template void walk_number(bool align) { DATA_SIMPLE(W, walk_number()); } }; @@ -893,6 +910,15 @@ data::walk_tag(bool align, tag_info &tinfo) { static_cast(this)->walk_tag(align, tinfo, tag_variant); } +template +void +data::walk_variant(bool align, tag_info &tinfo, uint32_t variant_id) { + std::pair variant_ptr_and_end = + this->get_variant_sp(tinfo, variant_id); + static_cast(this)->walk_variant(align, tinfo, variant_id, + variant_ptr_and_end); +} + // Copy constructors @@ -927,6 +953,16 @@ public: ptr_pair::make(in_data_0, in_data_1)), result(0) {} + cmp(const cmp &other, + const uint8_t *in_sp = NULL, + const type_param *in_params = NULL, + const rust_shape_tables *in_tables = NULL) + : data(other.task, + in_sp ? in_sp : other.sp, + in_params ? in_params : other.params, + in_tables ? in_tables : other.tables, + other.dp) {} + cmp(const cmp &other, const ptr_pair &in_dp) : data(other.task, other.sp, other.params, other.tables, in_dp), @@ -938,6 +974,9 @@ public: const data_pair &tag_variants); void walk_res(bool align, const rust_fn *dtor, uint16_t n_ty_params, const uint8_t *ty_params_sp); + void walk_variant(bool align, tag_info &tinfo, uint32_t variant_id, + const std::pair + variant_ptr_and_end); template void walk_number() { cmp_number(bump_dp(dp)); } @@ -966,7 +1005,7 @@ cmp::walk_tag(bool align, tag_info &tinfo, cmp_number(tag_variants); if (result != 0) return; - abort(); // TODO + data::walk_variant(align, tinfo, tag_variants.fst); } void @@ -975,6 +1014,19 @@ cmp::walk_res(bool align, const rust_fn *dtor, uint16_t n_ty_params, abort(); // TODO } +void +cmp::walk_variant(bool align, tag_info &tinfo, uint32_t variant_id, + const std::pair + variant_ptr_and_end) { + cmp sub(*this, variant_ptr_and_end.first); + + const uint8_t *variant_end = variant_ptr_and_end.second; + while (!sub.result && sub.sp < variant_end) { + sub.walk(align); + align = true; + } +} + } // end namespace shape extern "C" void -- cgit 1.4.1-3-g733a5