Skip to content

Commit 69068fe

Browse files
committed
---
yaml --- r: 4457 b: refs/heads/master c: 5261bd7 h: refs/heads/master i: 4455: 3be4011 v: v3
1 parent 1717036 commit 69068fe

File tree

2 files changed

+182
-78
lines changed

2 files changed

+182
-78
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
---
2-
refs/heads/master: a9471d82961eb18d60509247d827ce495210abbe
2+
refs/heads/master: 5261bd771f176c88e6f72aa4c87a6effb1240ac5

trunk/src/rt/rust_shape.cpp

Lines changed: 181 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,55 @@ round_up(T size, size_t alignment) {
7676
}
7777

7878

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+
79128

80129
// Contexts
81130

@@ -117,43 +166,6 @@ class ctxt {
117166
};
118167

119168

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-
157169
struct rust_fn {
158170
void (*code)(uint8_t *rv, rust_task *task, void *env, ...);
159171
void *env;
@@ -334,37 +346,38 @@ ctxt<T>::walk_ivec(bool align) {
334346
template<typename T>
335347
void
336348
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);
338351

339352
// 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;
342356

343-
uint16_t variant_count = get_u16_bump(info_ptr);
357+
tinfo.variant_count = get_u16_bump(tinfo.info_ptr);
344358

345359
// 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;
349362

350363
// 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);
352365

353366
// Determine the number of parameters.
354-
uint16_t n_params = get_u16_bump(sp);
367+
tinfo.n_params = get_u16_bump(sp);
355368

356369
// 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++) {
359372
uint16_t len = get_u16_bump(sp);
360373
params[i].set(this);
361374
sp += len;
362375
}
363376

377+
tinfo.params = params;
378+
364379
// 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);
368381
}
369382

370383
template<typename T>
@@ -430,10 +443,7 @@ class print : public ctxt<print> {
430443
const rust_shape_tables *in_tables = NULL)
431444
: ctxt<print>(other, in_sp, in_params, in_tables) {}
432445

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);
437447
void walk_struct(bool align, const uint8_t *end_sp);
438448
void walk_res(bool align, const rust_fn *dtor, uint16_t n_ty_params,
439449
const uint8_t *ty_params_sp);
@@ -466,23 +476,20 @@ class print : public ctxt<print> {
466476
};
467477

468478
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)
475482
return;
476483

477484
DPRINT("<");
478485

479486
bool first = true;
480-
for (uint16_t i = 0; i < n_params; i++) {
487+
for (uint16_t i = 0; i < tinfo.n_params; i++) {
481488
if (!first)
482489
DPRINT(",");
483490
first = false;
484491

485-
ctxt<print> sub(*this, params[i].shape);
492+
ctxt<print> sub(*this, tinfo.params[i].shape);
486493
sub.walk(align);
487494
}
488495

@@ -575,10 +582,7 @@ class size_of : public ctxt<size_of> {
575582
const rust_shape_tables *in_tables)
576583
: ctxt<size_of>(other, in_sp, in_params, in_tables) {}
577584

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);
582586
void walk_struct(bool align, const uint8_t *end_sp);
583587
void walk_ivec(bool align, bool is_pod, size_align &elem_sa);
584588

@@ -618,21 +622,18 @@ class size_of : public ctxt<size_of> {
618622
};
619623

620624
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) {
625626
// 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;
628629
return;
629630
}
630631

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);
632633
sa.set(0, 0);
633634
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 +
636637
variant_id * sizeof(uint16_t));
637638
const uint8_t *variant_ptr = tables->tags + variant_offset;
638639

@@ -657,7 +658,7 @@ size_of::walk_tag(bool align, uint16_t tag_id, const uint8_t *info_ptr,
657658
sa = variant_sa;
658659
}
659660

660-
if (variant_count == 1) {
661+
if (tinfo.variant_count == 1) {
661662
if (!sa.size)
662663
sa.set(1, 1);
663664
} else {
@@ -694,5 +695,108 @@ size_of::walk_ivec(bool align, bool is_pod, size_align &elem_sa) {
694695
max(sa.alignment, sizeof(uintptr_t)));
695696
}
696697

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+
697801
} // end namespace shape
698802

0 commit comments

Comments
 (0)