rt: Allow closures to be logged

This commit is contained in:
Patrick Walton 2011-08-26 17:05:05 -07:00
parent b894069a8f
commit 5fe80a0d48
3 changed files with 52 additions and 11 deletions

View File

@ -942,11 +942,12 @@ fn trans_stack_local_derived_tydesc(cx: &@block_ctxt, llsz: ValueRef,
ret llmyroottydesc;
}
// Objects store their type parameters differently (in the object itself
// rather than in the type descriptor).
// Objects and closures store their type parameters differently (in the object
// or closure itself rather than in the type descriptor).
tag ty_param_storage {
tps_normal;
tps_obj(uint);
tps_fn(uint);
}
fn get_derived_tydesc(cx: &@block_ctxt, t: ty::t, escapes: bool,
@ -1004,10 +1005,13 @@ fn get_derived_tydesc(cx: &@block_ctxt, t: ty::t, escapes: bool,
bld::PointerCast(bcx, llparamtydescs,
T_ptr(T_ptr(bcx_ccx(bcx).tydesc_type)));
// The top bit indicates whether this type descriptor describes an object
// (0) or a function (1).
let obj_params;
alt storage {
tps_normal. { obj_params = 0u; }
tps_obj(np) { obj_params = np; }
tps_fn(np) { obj_params = 0x80000000u | np; }
}
let v;

View File

@ -42,7 +42,17 @@ type_param::make(const type_desc **tydescs, unsigned n_tydescs,
return ptrs;
}
// Constructs type parameters from an object shape. This is a bit messy,
// Constructs type parameters from a function shape. This is a bit messy,
// because it requires that the function shape have a specific format.
type_param *
type_param::from_fn_shape(const uint8_t *sp, ptr dp, arena &arena) {
const type_desc *tydesc = bump_dp<const type_desc *>(dp);
const type_desc **descs = (const type_desc **)(dp + tydesc->size);
unsigned n_tydescs = tydesc->n_obj_params & 0x7fffffff;
return make(descs, n_tydescs, arena);
}
// Constructs type parameters from an object shape. This is also a bit messy,
// because it requires that the object shape have a specific format.
type_param *
type_param::from_obj_shape(const uint8_t *sp, ptr dp, arena &arena) {
@ -460,12 +470,6 @@ log::walk_vec(bool align, bool is_pod, const std::pair<ptr,ptr> &data) {
out << "]";
}
void
log::walk_obj(bool align) {
out << "obj";
data<log,ptr>::walk_obj_contents(align, dp);
}
void
log::walk_variant(bool align, tag_info &tinfo, uint32_t variant_id,
const std::pair<const uint8_t *,const uint8_t *>

View File

@ -245,6 +245,8 @@ public:
const rust_shape_tables *tables;
const type_param *params; // subparameters
// Constructs type parameters from a function shape.
static type_param *from_fn_shape(const uint8_t *sp, ptr dp, arena &arena);
// Creates type parameters from an object shape description.
static type_param *from_obj_shape(const uint8_t *sp, ptr dp,
arena &arena);
@ -718,6 +720,7 @@ template<typename T,typename U>
class data : public ctxt< data<T,U> > {
protected:
void walk_box_contents(bool align);
void walk_fn_contents(bool align, ptr &dp);
void walk_obj_contents(bool align, ptr &dp);
void walk_variant(bool align, tag_info &tinfo, uint32_t variant);
@ -894,6 +897,28 @@ data<T,U>::walk_tag(bool align, tag_info &tinfo) {
dp = end_dp;
}
template<typename T,typename U>
void
data<T,U>::walk_fn_contents(bool align, ptr &dp) {
dp += sizeof(void *); // Skip over the code pointer.
uint8_t *box_ptr = bump_dp<uint8_t *>(dp);
type_desc *subtydesc =
*reinterpret_cast<type_desc **>(box_ptr + sizeof(void *));
ptr closure_dp(box_ptr + sizeof(void *));
if (!box_ptr)
return;
arena arena;
type_param *params = type_param::from_fn_shape(subtydesc->shape,
closure_dp, arena);
closure_dp += sizeof(void *);
T sub(*static_cast<T *>(this), subtydesc->shape, params,
subtydesc->shape_tables, closure_dp);
sub.walk(true);
}
template<typename T,typename U>
void
data<T,U>::walk_obj_contents(bool align, ptr &dp) {
@ -967,7 +992,16 @@ private:
data<log,ptr>::walk_box_contents(align);
}
void walk_fn(bool align) { out << "fn"; }
void walk_fn(bool align) {
out << "fn";
data<log,ptr>::walk_fn_contents(align, dp);
}
void walk_obj(bool align) {
out << "obj";
data<log,ptr>::walk_obj_contents(align, dp);
}
void walk_port(bool align) { out << "port"; }
void walk_chan(bool align) { out << "chan"; }
void walk_task(bool align) { out << "task"; }
@ -988,7 +1022,6 @@ private:
void walk_struct(bool align, const uint8_t *end_sp);
void walk_vec(bool align, bool is_pod, const std::pair<ptr,ptr> &data);
void walk_obj(bool align);
void walk_variant(bool align, tag_info &tinfo, uint32_t variant_id,
const std::pair<const uint8_t *,const uint8_t *>
variant_ptr_and_end);