rt: Stub compare glue

This commit is contained in:
Patrick Walton 2011-08-05 18:47:12 -07:00
parent d7828e694d
commit 0aeddb3673

View file

@ -75,6 +75,14 @@ round_up(T size, size_t alignment) {
return x; return x;
} }
template<typename T>
static inline T
bump_dp(uint8_t *dp) {
T x = *((T *)dp);
dp += sizeof(T);
return x;
}
// Utility classes // Utility classes
@ -125,6 +133,34 @@ struct tag_info {
const type_param *params; // Array of type parameters. const type_param *params; // Array of type parameters.
}; };
template<typename T>
class data_pair {
public:
T fst, snd;
inline void operator=(const T rhs) { fst = snd = rhs; }
};
class ptr_pair {
public:
uint8_t *fst, *snd;
template<typename T>
class data { typedef data_pair<T> t; };
ptr_pair(uint8_t *in_fst, uint8_t *in_snd) : fst(in_fst), snd(in_snd) {}
inline void operator=(uint8_t *rhs) { fst = snd = rhs; }
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;
}
};
// Contexts // Contexts
@ -719,16 +755,15 @@ size_of::walk_ivec(bool align, bool is_pod, size_align &elem_sa) {
// for methods that actually manipulate the data involved. // for methods that actually manipulate the data involved.
#define DATA_SIMPLE(ty, call) \ #define DATA_SIMPLE(ty, call) \
if (align) dp.align_to(sizeof(ty)); \ if (align) dp = align_to(dp, sizeof(ty)); \
static_cast<T *>(this)->call; \ static_cast<T *>(this)->call; \
dp += sizeof(ty); dp += sizeof(ty);
template<typename T> template<typename T,typename U>
class data : public ctxt< data<T> > { class data : public ctxt< data<T,U> > {
private:
typename T::data_ptr dp;
public: public:
U dp;
void walk_tag(bool align, tag_info &tinfo); void walk_tag(bool align, tag_info &tinfo);
void walk_ivec(bool align, bool is_pod, size_align &elem_sa); void walk_ivec(bool align, bool is_pod, size_align &elem_sa);
@ -750,13 +785,13 @@ public:
void walk_task(bool align) { DATA_SIMPLE(void *, walk_task(align)); } void walk_task(bool align) { DATA_SIMPLE(void *, walk_task(align)); }
void walk_fn(bool align) { void walk_fn(bool align) {
if (align) dp.align_to(sizeof(void *)); if (align) dp = align_to(dp, sizeof(void *));
static_cast<T *>(this)->walk_fn(align); static_cast<T *>(this)->walk_fn(align);
dp += sizeof(void *) * 2; dp += sizeof(void *) * 2;
} }
void walk_obj(bool align) { void walk_obj(bool align) {
if (align) dp.align_to(sizeof(void *)); if (align) dp = align_to(dp, sizeof(void *));
static_cast<T *>(this)->walk_obj(align); static_cast<T *>(this)->walk_obj(align);
dp += sizeof(void *) * 2; dp += sizeof(void *) * 2;
} }
@ -766,23 +801,20 @@ public:
} }
template<typename W> template<typename W>
void walk_number(bool align) { void walk_number(bool align) { DATA_SIMPLE(W, walk_number<W>(align)); }
DATA_SIMPLE(W, walk_number<W>(align));
}
}; };
template<typename T> template<typename T,typename U>
void void
data<T>::walk_ivec(bool align, bool is_pod, size_align &elem_sa) { data<T,U>::walk_ivec(bool align, bool is_pod, size_align &elem_sa) {
if (!elem_sa.is_set()) if (!elem_sa.is_set())
elem_sa = size_of::get(*this); elem_sa = size_of::get(*this);
else if (elem_sa.alignment == 8) else if (elem_sa.alignment == 8)
elem_sa.alignment = 4; // FIXME: This is an awful hack. elem_sa.alignment = 4; // FIXME: This is an awful hack.
// Get a pointer to the interior vector, and skip over it. // Get a pointer to the interior vector, and skip over it.
if (align) dp.align_to(ALIGNOF(rust_ivec *)); if (align) dp = align_to(dp, ALIGNOF(rust_ivec *));
typename T::data_ptr end_dp = dp + sizeof(rust_ivec) - sizeof(uintptr_t) + U end_dp = dp + sizeof(rust_ivec) - sizeof(uintptr_t) + elem_sa.size * 4;
elem_sa.size * 4;
// Call to the implementation. // Call to the implementation.
static_cast<T *>(this)->walk_ivec(align, is_pod, elem_sa); static_cast<T *>(this)->walk_ivec(align, is_pod, elem_sa);
@ -790,19 +822,19 @@ data<T>::walk_ivec(bool align, bool is_pod, size_align &elem_sa) {
dp = end_dp; dp = end_dp;
} }
template<typename T> template<typename T,typename U>
void void
data<T>::walk_tag(bool align, tag_info &tinfo) { data<T,U>::walk_tag(bool align, tag_info &tinfo) {
size_of::compute_tag_size(tinfo); size_of::compute_tag_size(tinfo);
if (tinfo.variant_count > 1 && align) if (tinfo.variant_count > 1 && align)
dp.align_to(ALIGNOF(uint32_t)); dp = align_to(dp, ALIGNOF(uint32_t));
typename T::data_ptr end_dp = tinfo.tag_sa.size; U end_dp = tinfo.tag_sa.size;
typename T::template data<uint32_t> tag_variant; typename U::template data<uint32_t>::t tag_variant;
if (tinfo.variant_count > 1) if (tinfo.variant_count > 1)
tag_variant = dp.template get_bump<uint32_t>(); tag_variant = bump_dp<uint32_t>(dp);
else else
tag_variant = 0; tag_variant = 0;
@ -820,5 +852,11 @@ class copy : public data<copy> {
#endif #endif
// Structural comparison glue.
class cmp : public data<cmp,ptr_pair> {
};
} // end namespace shape } // end namespace shape