@@ -76,6 +76,55 @@ round_up(T size, size_t alignment) {
76
76
}
77
77
78
78
79
+ // Utility classes
80
+
81
+ struct size_align {
82
+ size_t size;
83
+ size_t alignment;
84
+
85
+ size_align (size_t in_size = 0 , size_t in_align = 1 ) :
86
+ size (in_size), alignment(in_align) {}
87
+
88
+ bool is_set () const { return alignment != 0 ; }
89
+
90
+ inline void set (size_t in_size, size_t in_align) {
91
+ size = in_size;
92
+ alignment = in_align;
93
+ }
94
+
95
+ inline void add (const size_align &other) {
96
+ add (other.size , other.alignment );
97
+ }
98
+
99
+ inline void add (size_t extra_size, size_t extra_align) {
100
+ size += extra_size;
101
+ alignment = max (alignment, extra_align);
102
+ }
103
+
104
+ static inline size_align make (size_t in_size) {
105
+ size_align sa;
106
+ sa.size = sa.alignment = in_size;
107
+ return sa;
108
+ }
109
+
110
+ static inline size_align make (size_t in_size, size_t in_align) {
111
+ size_align sa;
112
+ sa.size = in_size;
113
+ sa.alignment = in_align;
114
+ return sa;
115
+ }
116
+ };
117
+
118
+ struct tag_info {
119
+ uint16_t tag_id; // The tag ID.
120
+ const uint8_t *info_ptr; // Pointer to the info table.
121
+ uint16_t variant_count; // Number of variants in the tag.
122
+ const uint8_t *largest_variants_ptr; // Ptr to largest variants table.
123
+ size_align tag_sa; // Size and align of this tag.
124
+ uint16_t n_params; // Number of type parameters.
125
+ const type_param *params; // Array of type parameters.
126
+ };
127
+
79
128
80
129
// Contexts
81
130
@@ -117,43 +166,6 @@ class ctxt {
117
166
};
118
167
119
168
120
- struct size_align {
121
- size_t size;
122
- size_t alignment;
123
-
124
- size_align (size_t in_size = 0 , size_t in_align = 1 ) :
125
- size (in_size), alignment(in_align) {}
126
-
127
- bool is_set () const { return alignment != 0 ; }
128
-
129
- inline void set (size_t in_size, size_t in_align) {
130
- size = in_size;
131
- alignment = in_align;
132
- }
133
-
134
- inline void add (const size_align &other) {
135
- add (other.size , other.alignment );
136
- }
137
-
138
- inline void add (size_t extra_size, size_t extra_align) {
139
- size += extra_size;
140
- alignment = max (alignment, extra_align);
141
- }
142
-
143
- static inline size_align make (size_t in_size) {
144
- size_align sa;
145
- sa.size = sa.alignment = in_size;
146
- return sa;
147
- }
148
-
149
- static inline size_align make (size_t in_size, size_t in_align) {
150
- size_align sa;
151
- sa.size = in_size;
152
- sa.alignment = in_align;
153
- return sa;
154
- }
155
- };
156
-
157
169
struct rust_fn {
158
170
void (*code)(uint8_t *rv, rust_task *task, void *env, ...);
159
171
void *env;
@@ -334,37 +346,38 @@ ctxt<T>::walk_ivec(bool align) {
334
346
template <typename T>
335
347
void
336
348
ctxt<T>::walk_tag(bool align) {
337
- uint16_t tag_id = get_u16_bump (sp);
349
+ tag_info tinfo;
350
+ tinfo.tag_id = get_u16_bump (sp);
338
351
339
352
// Determine the info pointer.
340
- uint16_t info_offset = get_u16 (tables->tags + tag_id * sizeof (uint16_t ));
341
- const uint8_t *info_ptr = tables->tags + info_offset;
353
+ uint16_t info_offset = get_u16 (tables->tags +
354
+ tinfo.tag_id * sizeof (uint16_t ));
355
+ tinfo.info_ptr = tables->tags + info_offset;
342
356
343
- uint16_t variant_count = get_u16_bump (info_ptr);
357
+ tinfo. variant_count = get_u16_bump (tinfo. info_ptr );
344
358
345
359
// Determine the largest-variants pointer.
346
- uint16_t largest_variants_offset = get_u16_bump (info_ptr);
347
- const uint8_t *largest_variants_ptr =
348
- tables->tags + largest_variants_offset;
360
+ uint16_t largest_variants_offset = get_u16_bump (tinfo.info_ptr );
361
+ tinfo.largest_variants_ptr = tables->tags + largest_variants_offset;
349
362
350
363
// Determine the size and alignment.
351
- size_align tag_sa = get_size_align (info_ptr);
364
+ tinfo. tag_sa = get_size_align (tinfo. info_ptr );
352
365
353
366
// Determine the number of parameters.
354
- uint16_t n_params = get_u16_bump (sp);
367
+ tinfo. n_params = get_u16_bump (sp);
355
368
356
369
// Read in the tag type parameters.
357
- type_param params[n_params];
358
- for (uint16_t i = 0 ; i < n_params; i++) {
370
+ type_param params[tinfo. n_params ];
371
+ for (uint16_t i = 0 ; i < tinfo. n_params ; i++) {
359
372
uint16_t len = get_u16_bump (sp);
360
373
params[i].set (this );
361
374
sp += len;
362
375
}
363
376
377
+ tinfo.params = params;
378
+
364
379
// Call to the implementation.
365
- static_cast <T *>(this )->walk_tag (align, tag_id, info_ptr, variant_count,
366
- largest_variants_ptr, tag_sa, n_params,
367
- params);
380
+ static_cast <T *>(this )->walk_tag (align, tinfo);
368
381
}
369
382
370
383
template <typename T>
@@ -430,10 +443,7 @@ class print : public ctxt<print> {
430
443
const rust_shape_tables *in_tables = NULL )
431
444
: ctxt<print>(other, in_sp, in_params, in_tables) {}
432
445
433
- void walk_tag (bool align, uint16_t tag_id, const uint8_t *info_ptr,
434
- uint16_t variant_count, const uint8_t *largest_variants_ptr,
435
- size_align &tag_sa, uint16_t n_params,
436
- const type_param *params);
446
+ void walk_tag (bool align, tag_info &tinfo);
437
447
void walk_struct (bool align, const uint8_t *end_sp);
438
448
void walk_res (bool align, const rust_fn *dtor, uint16_t n_ty_params,
439
449
const uint8_t *ty_params_sp);
@@ -466,23 +476,20 @@ class print : public ctxt<print> {
466
476
};
467
477
468
478
void
469
- print::walk_tag (bool align, uint16_t tag_id, const uint8_t *info_ptr,
470
- uint16_t variant_count, const uint8_t *largest_variants_ptr,
471
- size_align &tag_sa, uint16_t n_params,
472
- const type_param *params) {
473
- DPRINT (" tag%u" , tag_id);
474
- if (!n_params)
479
+ print::walk_tag (bool align, tag_info &tinfo) {
480
+ DPRINT (" tag%u" , tinfo.tag_id );
481
+ if (!tinfo.n_params )
475
482
return ;
476
483
477
484
DPRINT (" <" );
478
485
479
486
bool first = true ;
480
- for (uint16_t i = 0 ; i < n_params; i++) {
487
+ for (uint16_t i = 0 ; i < tinfo. n_params ; i++) {
481
488
if (!first)
482
489
DPRINT (" ," );
483
490
first = false ;
484
491
485
- ctxt<print> sub (*this , params[i].shape );
492
+ ctxt<print> sub (*this , tinfo. params [i].shape );
486
493
sub.walk (align);
487
494
}
488
495
@@ -575,10 +582,7 @@ class size_of : public ctxt<size_of> {
575
582
const rust_shape_tables *in_tables)
576
583
: ctxt<size_of>(other, in_sp, in_params, in_tables) {}
577
584
578
- void walk_tag (bool align, uint16_t tag_id, const uint8_t *info_ptr,
579
- uint16_t variant_count, const uint8_t *largest_variants_ptr,
580
- size_align &tag_sa, uint16_t n_params,
581
- const type_param *params);
585
+ void walk_tag (bool align, tag_info &tinfo);
582
586
void walk_struct (bool align, const uint8_t *end_sp);
583
587
void walk_ivec (bool align, bool is_pod, size_align &elem_sa);
584
588
@@ -618,21 +622,18 @@ class size_of : public ctxt<size_of> {
618
622
};
619
623
620
624
void
621
- size_of::walk_tag (bool align, uint16_t tag_id, const uint8_t *info_ptr,
622
- uint16_t variant_count, const uint8_t *largest_variants_ptr,
623
- size_align &tag_sa, uint16_t n_params,
624
- const type_param *params) {
625
+ size_of::walk_tag (bool align, tag_info &tinfo) {
625
626
// If the precalculated size and alignment are good, use them.
626
- if (tag_sa.is_set ()) {
627
- sa = tag_sa;
627
+ if (tinfo. tag_sa .is_set ()) {
628
+ sa = tinfo. tag_sa ;
628
629
return ;
629
630
}
630
631
631
- uint16_t n_largest_variants = get_u16_bump (largest_variants_ptr);
632
+ uint16_t n_largest_variants = get_u16_bump (tinfo. largest_variants_ptr );
632
633
sa.set (0 , 0 );
633
634
for (uint16_t i = 0 ; i < n_largest_variants; i++) {
634
- uint16_t variant_id = get_u16_bump (largest_variants_ptr);
635
- uint16_t variant_offset = get_u16 (info_ptr +
635
+ uint16_t variant_id = get_u16_bump (tinfo. largest_variants_ptr );
636
+ uint16_t variant_offset = get_u16 (tinfo. info_ptr +
636
637
variant_id * sizeof (uint16_t ));
637
638
const uint8_t *variant_ptr = tables->tags + variant_offset;
638
639
@@ -657,7 +658,7 @@ size_of::walk_tag(bool align, uint16_t tag_id, const uint8_t *info_ptr,
657
658
sa = variant_sa;
658
659
}
659
660
660
- if (variant_count == 1 ) {
661
+ if (tinfo. variant_count == 1 ) {
661
662
if (!sa.size )
662
663
sa.set (1 , 1 );
663
664
} else {
@@ -694,5 +695,108 @@ size_of::walk_ivec(bool align, bool is_pod, size_align &elem_sa) {
694
695
max (sa.alignment , sizeof (uintptr_t )));
695
696
}
696
697
698
+
699
+ #if 0
700
+
701
+ // An abstract class (again using the curiously recurring template pattern)
702
+ // for methods that actually manipulate the data involved.
703
+
704
+ #define DATA_SIMPLE(ty, call) \
705
+ if (align) dp.align(sizeof(ty)); \
706
+ static_cast<T *>(this)->call; \
707
+ dp += sizeof(ty);
708
+
709
+ template<typename T,typename U>
710
+ class data : public ctxt<data> {
711
+ private:
712
+ U dp;
713
+
714
+ public:
715
+ void walk_tag(bool align, uint16_t tag_id, const uint8_t *info_ptr,
716
+ uint16_t variant_count, const uint8_t *largest_variants_ptr,
717
+ size_align &tag_sa, uint16_t n_params,
718
+ const type_param *params);
719
+ void walk_ivec(bool align, bool is_pod, size_align &elem_sa);
720
+
721
+ void walk_struct(bool align, const uint8_t *end_sp) {
722
+ while (sp != end_sp) {
723
+ // TODO: Allow subclasses to optimize for POD if they want to.
724
+ walk(align);
725
+ align = true;
726
+ }
727
+ }
728
+
729
+ void walk_evec(bool align, bool is_pod, uint16_t sp_size) {
730
+ DATA_SIMPLE(void *, walk_evec(align, is_pod, sp_size));
731
+ }
732
+
733
+ void walk_box(bool align) { DATA_SIMPLE(void *, walk_box(align)); }
734
+ void walk_port(bool align) { DATA_SIMPLE(void *, walk_port(align)); }
735
+ void walk_chan(bool align) { DATA_SIMPLE(void *, walk_chan(align)); }
736
+ void walk_task(bool align) { DATA_SIMPLE(void *, walk_task(align)); }
737
+
738
+ void walk_fn(bool align) {
739
+ if (align) dp.align(sizeof(void *));
740
+ static_cast<T *>(this)->walk_fn(args);
741
+ dp += sizeof(void *) * 2;
742
+ }
743
+
744
+ void walk_obj(bool align) {
745
+ if (align) dp.align(sizeof(void *));
746
+ static_cast<T *>(this)->walk_obj(args);
747
+ dp += sizeof(void *) * 2;
748
+ }
749
+
750
+ void walk_var(bool align, uint8_t param_index) {
751
+ static_cast<T *>(this)->walk_var(align, param_index);
752
+ }
753
+
754
+ template<typename W>
755
+ void walk_number(bool align) {
756
+ DATA_SIMPLE(W, walk_number<W>(align));
757
+ }
758
+ };
759
+
760
+ template<typename T,typename U>
761
+ void
762
+ data<T,U>::walk_ivec(bool align, bool is_pod, size_align &elem_sa) {
763
+ if (!elem_sa.is_set())
764
+ elem_sa = size_of::get(*this);
765
+ else if (elem_sa.alignment == 8)
766
+ elem_sa.alignment = 4; // FIXME: This is an awful hack.
767
+
768
+ // Get a pointer to the interior vector, and skip over it.
769
+ if (align) dp.align(ALIGNOF(rust_ivec *));
770
+ U end_dp = dp + sizeof(rust_ivec) - sizeof(uintptr_t) + elem_sa.size * 4;
771
+
772
+ // Call to the implementation.
773
+ static_cast<T *>(this)->walk_ivec(align, is_pod, elem_sa);
774
+
775
+ dp = end_dp;
776
+ }
777
+
778
+ template<typename T,typename U>
779
+ void
780
+ data<T,U>::walk_tag(bool align, uint16_t tag_id, const uint8_t *info_ptr,
781
+ uint16_t variant_count,
782
+ const uint8_t *largest_variants_ptr, size_align &tag_sa,
783
+ uint16_t n_params, const type_param *params) {
784
+ uint32_t tag_variant;
785
+ U end_dp;
786
+ if (variant_count > 1) {
787
+ if (align) dp.align(ALIGNOF(uint32_t));
788
+ process_tag_variant_ids(
789
+ U::data<uint32_t> tag_variant =
790
+ }
791
+
792
+ #endif
793
+
794
+
795
+ // Copy constructors
796
+
797
+ class copy : public ctxt <copy> {
798
+ // TODO
799
+ };
800
+
697
801
} // end namespace shape
698
802
0 commit comments