From b371891c7c35f5d561a4847515e41014c652fa26 Mon Sep 17 00:00:00 2001 From: Patrick Walton Date: Wed, 24 Aug 2011 16:54:10 -0700 Subject: [PATCH] rt: Fix walk_obj_contents for type-parameteric objects. Hash tables can be logged now. --- src/rt/rust_shape.cpp | 17 ++++++++++++--- src/rt/rust_shape.h | 51 +++++++++++++++++++++++-------------------- 2 files changed, 41 insertions(+), 27 deletions(-) diff --git a/src/rt/rust_shape.cpp b/src/rt/rust_shape.cpp index 8e99c41ea02..6a586860cd6 100644 --- a/src/rt/rust_shape.cpp +++ b/src/rt/rust_shape.cpp @@ -42,10 +42,21 @@ type_param::make(const type_desc **tydescs, unsigned n_tydescs, return ptrs; } +// Constructs type parameters from an object shape. This is 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, arena &arena) { - // TODO - abort(); +type_param::from_obj_shape(const uint8_t *sp, ptr dp, arena &arena) { + uint8_t shape = *sp++; assert(shape == SHAPE_STRUCT); + get_u16_bump(sp); // Skip over the size. + shape = *sp++; assert(shape == SHAPE_PTR); + shape = *sp++; assert(shape == SHAPE_STRUCT); + + unsigned n_tydescs = get_u16_bump(sp); + + // Type descriptors start right after the reference count. + const type_desc **descs = (const type_desc **)(dp + sizeof(uintptr_t)); + + return make(descs, n_tydescs, arena); } diff --git a/src/rt/rust_shape.h b/src/rt/rust_shape.h index e735bfa3d1b..0302338e26d 100644 --- a/src/rt/rust_shape.h +++ b/src/rt/rust_shape.h @@ -46,11 +46,18 @@ const uint8_t SHAPE_OBJ = 19u; const uint8_t SHAPE_RES = 20u; const uint8_t SHAPE_VAR = 21u; +#ifdef _LP64 +const uint8_t SHAPE_PTR = SHAPE_U64; +#else +const uint8_t SHAPE_PTR = SHAPE_U32; +#endif + // Forward declarations struct rust_obj; struct size_align; +class ptr; class type_param; @@ -129,6 +136,21 @@ struct tag_info { }; +// Utility functions + +inline uint16_t +get_u16(const uint8_t *addr) { + return *reinterpret_cast(addr); +} + +inline uint16_t +get_u16_bump(const uint8_t *&addr) { + uint16_t result = get_u16(addr); + addr += sizeof(uint16_t); + return result; +} + + // Contexts // The base context, an abstract class. We use the curiously recurring @@ -166,8 +188,6 @@ public: protected: inline uint8_t peek() { return *sp; } - static inline uint16_t get_u16(const uint8_t *addr); - static inline uint16_t get_u16_bump(const uint8_t *&addr); inline size_align get_size_align(const uint8_t *&addr); private: @@ -226,7 +246,8 @@ public: const type_param *params; // subparameters // Creates type parameters from an object shape description. - static type_param *from_obj_shape(const uint8_t *sp, arena &arena); + static type_param *from_obj_shape(const uint8_t *sp, ptr dp, + arena &arena); template inline void set(ctxt *cx) { @@ -284,20 +305,6 @@ ctxt::walk_reset(bool align) { sp = old_sp; } -template -uint16_t -ctxt::get_u16(const uint8_t *addr) { - return *reinterpret_cast(addr); -} - -template -uint16_t -ctxt::get_u16_bump(const uint8_t *&addr) { - uint16_t result = get_u16(addr); - addr += sizeof(uint16_t); - return result; -} - template size_align ctxt::get_size_align(const uint8_t *&addr) { @@ -892,17 +899,13 @@ data::walk_obj_contents(bool align, ptr &dp) { uint8_t *box_ptr = bump_dp(dp); type_desc *subtydesc = *reinterpret_cast(box_ptr + sizeof(void *)); - ptr obj_closure_dp(*box_ptr + sizeof(void *)); + ptr obj_closure_dp(box_ptr + sizeof(void *)); - // FIXME: Should be type_param::from_obj_shape() below. arena arena; - type_param *params = type_param::from_tydesc(subtydesc, arena); + type_param *params = type_param::from_obj_shape(subtydesc->shape, + obj_closure_dp, arena); T sub(*static_cast(this), subtydesc->shape, params, subtydesc->shape_tables, obj_closure_dp); - - print print(sub); - print.walk(false); - sub.walk(true); }