@@ -69,7 +69,7 @@ const uint8_t CMP_LE = 2u;
69
69
// of two.
70
70
template <typename T>
71
71
static inline T
72
- round_up (T size, size_t alignment) {
72
+ align_to (T size, size_t alignment) {
73
73
assert (alignment);
74
74
T x = (T)(((uintptr_t )size + alignment - 1 ) & ~(alignment - 1 ));
75
75
return x;
@@ -133,10 +133,17 @@ struct tag_info {
133
133
const type_param *params; // Array of type parameters.
134
134
};
135
135
136
+
137
+ // Pointer pairs for structural comparison
138
+
136
139
template <typename T>
137
140
class data_pair {
138
141
public:
139
142
T fst, snd;
143
+
144
+ data_pair () {}
145
+ data_pair (T &in_fst, T &in_snd) : fst(in_fst), snd(in_snd) {}
146
+
140
147
inline void operator =(const T rhs) { fst = snd = rhs; }
141
148
};
142
149
@@ -145,7 +152,7 @@ class ptr_pair {
145
152
uint8_t *fst, *snd;
146
153
147
154
template <typename T>
148
- class data { typedef data_pair<T> t; };
155
+ struct data { typedef data_pair<T> t; };
149
156
150
157
ptr_pair (uint8_t *in_fst, uint8_t *in_snd) : fst(in_fst), snd(in_snd) {}
151
158
@@ -155,12 +162,36 @@ class ptr_pair {
155
162
return make (fst + n, snd + n);
156
163
}
157
164
165
+ inline ptr_pair operator +=(size_t n) {
166
+ fst += n; snd += n;
167
+ return *this ;
168
+ }
169
+
170
+ inline ptr_pair operator -(size_t n) const {
171
+ return make (fst - n, snd - n);
172
+ }
173
+
158
174
static inline ptr_pair make (uint8_t *fst, uint8_t *snd) {
159
175
ptr_pair self (fst, snd);
160
176
return self;
161
177
}
162
178
};
163
179
180
+ inline ptr_pair
181
+ align_to (const ptr_pair const &pair, size_t n) {
182
+ return ptr_pair::make (align_to (pair.fst , n), align_to (pair.snd , n));
183
+ }
184
+
185
+ // NB: This function does not align.
186
+ template <typename T>
187
+ inline data_pair<T>
188
+ bump_dp (ptr_pair &ptr) {
189
+ data_pair<T> data (*reinterpret_cast <T *>(ptr.fst ),
190
+ *reinterpret_cast <T *>(ptr.snd ));
191
+ ptr += sizeof (T);
192
+ return data;
193
+ }
194
+
164
195
165
196
// Contexts
166
197
@@ -174,6 +205,12 @@ class ctxt {
174
205
const rust_shape_tables *tables;
175
206
rust_task *task;
176
207
208
+ ctxt (rust_task *in_task,
209
+ const uint8_t *in_sp,
210
+ const type_param *in_params,
211
+ const rust_shape_tables *in_tables)
212
+ : sp(in_sp), params(in_params), tables(in_tables), task(in_task) {}
213
+
177
214
template <typename U>
178
215
ctxt (const ctxt<U> &other,
179
216
const uint8_t *in_sp = NULL ,
@@ -665,7 +702,7 @@ class size_of : public ctxt<size_of> {
665
702
666
703
template <typename T>
667
704
static size_align get (const ctxt<T> &other_cx, unsigned back_up = 0 ) {
668
- size_of cx (other_cx, other_cx-> sp - back_up);
705
+ size_of cx (other_cx, other_cx. sp - back_up);
669
706
cx.walk (false );
670
707
assert (cx.sa .alignment > 0 );
671
708
return cx.sa ;
@@ -696,7 +733,7 @@ size_of::compute_tag_size(tag_info &tinfo) {
696
733
bool first = true ;
697
734
while (sub.sp != variant_end) {
698
735
if (!first)
699
- variant_sa.size = round_up (variant_sa.size , sub.sa .alignment );
736
+ variant_sa.size = align_to (variant_sa.size , sub.sa .alignment );
700
737
sub.walk (!first);
701
738
first = false ;
702
739
@@ -729,7 +766,7 @@ size_of::walk_struct(bool align, const uint8_t *end_sp) {
729
766
bool first = true ;
730
767
while (sp != end_sp) {
731
768
if (!first)
732
- struct_sa.size = round_up (struct_sa.size , sa.alignment );
769
+ struct_sa.size = align_to (struct_sa.size , sa.alignment );
733
770
walk (!first);
734
771
first = false ;
735
772
@@ -764,6 +801,13 @@ class data : public ctxt< data<T,U> > {
764
801
public:
765
802
U dp;
766
803
804
+ data (rust_task *in_task,
805
+ const uint8_t *in_sp,
806
+ const type_param *in_params,
807
+ const rust_shape_tables *in_tables,
808
+ U const &in_dp)
809
+ : ctxt< data<T,U> >(in_task, in_sp, in_params, in_tables), dp(in_dp) {}
810
+
767
811
void walk_tag (bool align, tag_info &tinfo);
768
812
void walk_ivec (bool align, bool is_pod, size_align &elem_sa);
769
813
@@ -796,12 +840,19 @@ class data : public ctxt< data<T,U> > {
796
840
dp += sizeof (void *) * 2 ;
797
841
}
798
842
843
+ void walk_res (bool align, const rust_fn *dtor, uint16_t n_ty_params,
844
+ const uint8_t *ty_params_sp) {
845
+ // Delegate to the implementation.
846
+ static_cast <T *>(this )->walk_res (align, dtor, n_ty_params,
847
+ ty_params_sp);
848
+ }
849
+
799
850
void walk_var (bool align, uint8_t param_index) {
800
851
static_cast <T *>(this )->walk_var (align, param_index);
801
852
}
802
853
803
854
template <typename W>
804
- void walk_number (bool align) { DATA_SIMPLE (W, walk_number<W>(align )); }
855
+ void walk_number (bool align) { DATA_SIMPLE (W, walk_number<W>()); }
805
856
};
806
857
807
858
template <typename T,typename U>
@@ -825,12 +876,12 @@ data<T,U>::walk_ivec(bool align, bool is_pod, size_align &elem_sa) {
825
876
template <typename T,typename U>
826
877
void
827
878
data<T,U>::walk_tag(bool align, tag_info &tinfo) {
828
- size_of::compute_tag_size (tinfo);
879
+ size_of::compute_tag_size (* this , tinfo);
829
880
830
881
if (tinfo.variant_count > 1 && align)
831
882
dp = align_to (dp, ALIGNOF (uint32_t ));
832
883
833
- U end_dp = tinfo.tag_sa .size ;
884
+ U end_dp = dp + tinfo.tag_sa .size ;
834
885
835
886
typename U::template data<uint32_t >::t tag_variant;
836
887
if (tinfo.variant_count > 1 )
@@ -846,7 +897,7 @@ data<T,U>::walk_tag(bool align, tag_info &tinfo) {
846
897
847
898
#if 0
848
899
849
- class copy : public data<copy> {
900
+ class copy : public data<copy,uint8_t * > {
850
901
// TODO
851
902
};
852
903
@@ -856,7 +907,67 @@ class copy : public data<copy> {
856
907
// Structural comparison glue.
857
908
858
909
class cmp : public data <cmp,ptr_pair> {
910
+ private:
911
+ template <typename T>
912
+ int cmp_number (ptr_pair &ptrs);
913
+
914
+ public:
915
+ int result;
916
+
917
+ cmp (rust_task *in_task,
918
+ const uint8_t *in_sp,
919
+ const type_param *in_params,
920
+ const rust_shape_tables *in_tables,
921
+ uint8_t *in_data_0,
922
+ uint8_t *in_data_1)
923
+ : data<cmp,ptr_pair>(in_task, in_sp, in_params, in_tables,
924
+ ptr_pair::make (in_data_0, in_data_1)) {}
925
+
926
+ void walk_tag (bool align, tag_info &tinfo,
927
+ data_pair<uint32_t > &tag_variants);
928
+ void walk_res (bool align, const rust_fn *dtor, uint16_t n_ty_params,
929
+ const uint8_t *ty_params_sp);
930
+
931
+ template <typename T>
932
+ void walk_number () { result = cmp_number<T>(dp); }
859
933
};
860
934
935
+ void
936
+ cmp::walk_tag (bool align, tag_info &tinfo,
937
+ data_pair<uint32_t > &tag_variants) {
938
+ abort (); // TODO
939
+ }
940
+
941
+ void
942
+ cmp::walk_res (bool align, const rust_fn *dtor, uint16_t n_ty_params,
943
+ const uint8_t *ty_params_sp) {
944
+ abort (); // TODO
945
+ }
946
+
947
+ template <typename T>
948
+ int
949
+ cmp::cmp_number (ptr_pair &ptrs) {
950
+ T a = *(reinterpret_cast <T *>(dp.fst ));
951
+ T b = *(reinterpret_cast <T *>(dp.snd ));
952
+ return (a < b) ? -1 : (a == b) ? 0 : 1 ;
953
+ }
954
+
861
955
} // end namespace shape
862
956
957
+ extern " C" void
958
+ upcall_cmp_type (int8_t *result, rust_task *task, type_desc *tydesc,
959
+ const type_desc **subtydescs, uint8_t *data_0,
960
+ uint8_t *data_1, uint8_t cmp_type) {
961
+ shape::arena arena;
962
+ shape::type_param *params = shape::type_param::make (tydesc, arena);
963
+ shape::cmp cmp (task, tydesc->shape , params, tydesc->shape_tables , data_0,
964
+ data_1);
965
+ cmp.walk (true );
966
+
967
+ switch (cmp_type) {
968
+ case shape::CMP_EQ: *result = cmp.result == 0 ; break ;
969
+ case shape::CMP_LT: *result = cmp.result < 0 ; break ;
970
+ case shape::CMP_LE: *result = cmp.result <= 0 ; break ;
971
+ }
972
+ }
973
+
0 commit comments