From 53ec6c3f9b495dd930cd061784251534bef58d74 Mon Sep 17 00:00:00 2001 From: Brian Anderson <banderson@mozilla.com> Date: Mon, 5 Nov 2012 13:43:32 -0800 Subject: [PATCH] rt: Remove shape code --- mk/rt.mk | 1 - src/rt/rust_shape.cpp | 542 ----------------- src/rt/rust_shape.h | 1314 ---------------------------------------- src/rt/rust_type.h | 9 +- src/rt/rust_upcall.cpp | 54 +- src/rt/rust_util.cpp | 14 +- src/rt/rustrt.def.in | 2 - 7 files changed, 8 insertions(+), 1928 deletions(-) delete mode 100644 src/rt/rust_shape.cpp delete mode 100644 src/rt/rust_shape.h diff --git a/mk/rt.mk b/mk/rt.mk index fd948fbc53a..efabfc39749 100644 --- a/mk/rt.mk +++ b/mk/rt.mk @@ -69,7 +69,6 @@ RUNTIME_CXXS_$(1) := \ rt/isaac/randport.cpp \ rt/miniz.cpp \ rt/rust_kernel.cpp \ - rt/rust_shape.cpp \ rt/rust_abi.cpp \ rt/rust_debug.cpp \ rt/memory_region.cpp \ diff --git a/src/rt/rust_shape.cpp b/src/rt/rust_shape.cpp deleted file mode 100644 index 8ad36af4ed2..00000000000 --- a/src/rt/rust_shape.cpp +++ /dev/null @@ -1,542 +0,0 @@ -// Functions that interpret the shape of a type to perform various low-level -// actions, such as copying, freeing, comparing, and so on. - - -#include <algorithm> -#include <iomanip> -#include <iostream> -#include <sstream> -#include <utility> - -#include "rust_task.h" -#include "rust_shape.h" - -namespace shape { - -using namespace shape; - -// Constants - -const uint8_t CMP_EQ = 0u; -const uint8_t CMP_LT = 1u; -const uint8_t CMP_LE = 2u; - -// A shape printer, useful for debugging - -void -print::walk_tag1(tag_info &tinfo) { - DPRINT("tag%u", tinfo.tag_id); -} - -void -print::walk_struct1(const uint8_t *end_sp) { - DPRINT("("); - - bool first = true; - while (sp != end_sp) { - if (!first) - DPRINT(","); - first = false; - - walk(); - } - - DPRINT(")"); -} - -void -print::walk_res1(const rust_fn *dtor, const uint8_t *end_sp) { - DPRINT("res@%p", dtor); - - // Print arguments. - - if (sp == end_sp) - return; - - DPRINT("("); - - bool first = true; - while (sp != end_sp) { - if (!first) - DPRINT(","); - first = false; - - walk(); - } - - DPRINT(")"); -} - -template<> -void print::walk_number1<uint8_t>() { DPRINT("u8"); } -template<> -void print::walk_number1<uint16_t>() { DPRINT("u16"); } -template<> -void print::walk_number1<uint32_t>() { DPRINT("u32"); } -template<> -void print::walk_number1<uint64_t>() { DPRINT("u64"); } -template<> -void print::walk_number1<int8_t>() { DPRINT("i8"); } -template<> -void print::walk_number1<int16_t>() { DPRINT("i16"); } -template<> -void print::walk_number1<int32_t>() { DPRINT("i32"); } -template<> -void print::walk_number1<int64_t>() { DPRINT("i64"); } -template<> -void print::walk_number1<float>() { DPRINT("f32"); } -template<> -void print::walk_number1<double>() { DPRINT("f64"); } - - -void -size_of::compute_tag_size(tag_info &tinfo) { - // If the precalculated size and alignment are good, use them. - if (tinfo.tag_sa.is_set()) - return; - - uint16_t n_largest_variants = get_u16_bump(tinfo.largest_variants_ptr); - tinfo.tag_sa.set(0, 0); - for (uint16_t i = 0; i < n_largest_variants; i++) { - uint16_t variant_id = get_u16_bump(tinfo.largest_variants_ptr); - std::pair<const uint8_t *,const uint8_t *> variant_ptr_and_end = - get_variant_sp(tinfo, variant_id); - const uint8_t *variant_ptr = variant_ptr_and_end.first; - const uint8_t *variant_end = variant_ptr_and_end.second; - - size_of sub(*this, variant_ptr, NULL); - sub.align = false; - - // Compute the size of this variant. - size_align variant_sa; - bool first = true; - while (sub.sp != variant_end) { - if (!first) - variant_sa.size = align_to(variant_sa.size, sub.sa.alignment); - sub.walk(); - sub.align = true, first = false; - - variant_sa.add(sub.sa.size, sub.sa.alignment); - } - - if (tinfo.tag_sa.size < variant_sa.size) - tinfo.tag_sa = variant_sa; - } - - if (tinfo.variant_count == 1) { - if (!tinfo.tag_sa.size) - tinfo.tag_sa.set(1, 1); - } else { - // Add in space for the tag. - tinfo.tag_sa.add(sizeof(tag_variant_t), rust_alignof<tag_align_t>()); - } -} - -void -size_of::walk_tag1(tag_info &tinfo) { - compute_tag_size(*this, tinfo); - sa = tinfo.tag_sa; -} - -void -size_of::walk_struct1(const uint8_t *end_sp) { - size_align struct_sa(0, 1); - - bool first = true; - while (sp != end_sp) { - if (!first) - struct_sa.size = align_to(struct_sa.size, sa.alignment); - walk(); - align = true, first = false; - - struct_sa.add(sa); - } - - sa = struct_sa; -} - -// Copy constructors - -#if 0 - -class copy : public data<copy,uint8_t *> { - // FIXME #2892 -}; - -#endif - - -// Structural comparison glue. - -class cmp : public data<cmp,ptr_pair> { - friend class data<cmp,ptr_pair>; - -private: - void walk_slice2(bool is_pod, - const std::pair<ptr_pair,ptr_pair> &data_range); - - void walk_vec2(bool is_pod, - const std::pair<ptr_pair,ptr_pair> &data_range); - - inline void walk_subcontext2(cmp &sub) { - sub.walk(); - result = sub.result; - } - - inline void walk_box_contents2(cmp &sub) { - sub.align = true; - sub.walk(); - result = sub.result; - } - - inline void walk_uniq_contents2(cmp &sub) { - sub.align = true; - sub.walk(); - result = sub.result; - } - - inline void walk_rptr_contents2(cmp &sub) { - sub.align = true; - sub.walk(); - result = sub.result; - } - - inline void cmp_two_pointers() { - ALIGN_TO(rust_alignof<void *>()); - data_pair<uint8_t *> fst = bump_dp<uint8_t *>(dp); - data_pair<uint8_t *> snd = bump_dp<uint8_t *>(dp); - cmp_number(fst); - if (!result) - cmp_number(snd); - } - - inline void cmp_pointer() { - ALIGN_TO(rust_alignof<void *>()); - cmp_number(bump_dp<uint8_t *>(dp)); - } - - template<typename T> - void cmp_number(const data_pair<T> &nums) { - result = (nums.fst < nums.snd) ? -1 : (nums.fst == nums.snd) ? 0 : 1; - } - -public: - int result; - - cmp(rust_task *in_task, - bool in_align, - const uint8_t *in_sp, - const rust_shape_tables *in_tables, - uint8_t *in_data_0, - uint8_t *in_data_1) - : data<cmp,ptr_pair>(in_task, in_align, in_sp, in_tables, - ptr_pair::make(in_data_0, in_data_1)), - result(0) {} - - cmp(const cmp &other, - const uint8_t *in_sp, - const rust_shape_tables *in_tables, - ptr_pair &in_dp) - : data<cmp,ptr_pair>(other.task, other.align, in_sp, in_tables, - in_dp), - result(0) {} - - cmp(const cmp &other, - const uint8_t *in_sp = NULL, - const rust_shape_tables *in_tables = NULL) - : data<cmp,ptr_pair>(other.task, - other.align, - in_sp ? in_sp : other.sp, - in_tables ? in_tables : other.tables, - other.dp), - result(0) {} - - cmp(const cmp &other, const ptr_pair &in_dp) - : data<cmp,ptr_pair>(other.task, - other.align, - other.sp, - other.tables, - in_dp), - result(0) {} - - void walk_vec2(bool is_pod) { - walk_vec2(is_pod, get_vec_data_range(dp)); - } - - void walk_unboxed_vec2(bool is_pod) { - walk_vec2(is_pod, get_unboxed_vec_data_range(dp)); - } - - - void walk_slice2(bool is_pod, bool is_str) { - // Slices compare just like vecs. - walk_vec2(is_pod, get_slice_data_range(is_str, dp)); - } - - void walk_fixedvec2(uint16_t n_elts, size_t elt_sz, bool is_pod) { - // Fixedvecs compare just like vecs. - walk_vec2(is_pod, get_fixedvec_data_range(n_elts, elt_sz, dp)); - } - - void walk_box2() { - data<cmp,ptr_pair>::walk_box_contents1(); - } - - void walk_uniq2() { - data<cmp,ptr_pair>::walk_uniq_contents1(); - } - - void walk_rptr2() { - data<cmp,ptr_pair>::walk_rptr_contents1(); - } - - void walk_trait2() { - data<cmp,ptr_pair>::walk_box_contents1(); - } - - void walk_tydesc2(char) { - cmp_pointer(); - } - - void walk_fn2(char) { return cmp_two_pointers(); } - void walk_obj2() { return cmp_two_pointers(); } - - void walk_tag2(tag_info &tinfo, - const data_pair<tag_variant_t> &tag_variants); - void walk_struct2(const uint8_t *end_sp); - void walk_res2(const rust_fn *dtor, const uint8_t *end_sp); - void walk_variant2(tag_info &tinfo, - tag_variant_t variant_id, - const std::pair<const uint8_t *,const uint8_t *> - variant_ptr_and_end); - - template<typename T> - void walk_number2() { cmp_number(get_dp<T>(dp)); } -}; - -template<> -void cmp::cmp_number<int32_t>(const data_pair<int32_t> &nums) { - result = (nums.fst < nums.snd) ? -1 : (nums.fst == nums.snd) ? 0 : 1; -} - -void -cmp::walk_vec2(bool is_pod, const std::pair<ptr_pair,ptr_pair> &data_range) { - cmp sub(*this, data_range.first); - ptr_pair data_end = sub.end_dp = data_range.second; - while (!result && sub.dp < data_end) { - sub.walk_reset(); - result = sub.result; - sub.align = true; - } - - if (!result) { - // If we hit the end, the result comes down to length comparison. - int len_fst = data_range.second.fst - data_range.first.fst; - int len_snd = data_range.second.snd - data_range.first.snd; - cmp_number(data_pair<int>::make(len_fst, len_snd)); - } -} - -void -cmp::walk_tag2(tag_info &tinfo, - const data_pair<tag_variant_t> &tag_variants) { - cmp_number(tag_variants); - if (result != 0) - return; - data<cmp,ptr_pair>::walk_variant1(tinfo, tag_variants.fst); -} - -void -cmp::walk_struct2(const uint8_t *end_sp) { - while (!result && this->sp != end_sp) { - this->walk(); - align = true; - } -} - -void -cmp::walk_res2(const rust_fn *dtor, const uint8_t *end_sp) { - this->cmp_two_pointers(); -} - -void -cmp::walk_variant2(tag_info &tinfo, - tag_variant_t variant_id, - const std::pair<const uint8_t *,const uint8_t *> - variant_ptr_and_end) { - cmp sub(*this, variant_ptr_and_end.first); - - const uint8_t *variant_end = variant_ptr_and_end.second; - while (!result && sub.sp < variant_end) { - sub.walk(); - result = sub.result; - sub.align = true; - } -} - - -// Polymorphic logging, for convenience - -void -log::walk_string2(const std::pair<ptr,ptr> &data) { - out << prefix << "\"" << std::hex; - - ptr subdp = data.first; - while (subdp < data.second) { - char ch = *subdp; - switch(ch) { - case '\n': out << "\\n"; break; - case '\r': out << "\\r"; break; - case '\t': out << "\\t"; break; - case '\\': out << "\\\\"; break; - case '"': out << "\\\""; break; - default: - if (isprint(ch)) { - out << ch; - } else if (ch) { - out << "\\x" << std::setw(2) << std::setfill('0') - << (unsigned int)(unsigned char)ch; - } - } - ++subdp; - } - - out << "\"" << std::dec; -} - -void -log::walk_struct2(const uint8_t *end_sp) { - out << prefix << "("; - prefix = ""; - - bool first = true; - while (sp != end_sp) { - if (!first) - out << ", "; - walk(); - align = true, first = false; - } - - out << ")"; -} - -void -log::walk_vec2(bool is_pod, const std::pair<ptr,ptr> &data) { - if (peek() == SHAPE_U8) { - sp++; // It's a string. We handle this ourselves. - walk_string2(data); - return; - } - - out << prefix << "["; - - log sub(*this, data.first); - sub.end_dp = data.second; - - while (sub.dp < data.second) { - sub.walk_reset(); - sub.align = true; - sub.prefix = ", "; - } - - out << "]"; -} - -void -log::walk_variant2(tag_info &tinfo, - tag_variant_t variant_id, - const std::pair<const uint8_t *,const uint8_t *> - variant_ptr_and_end) { - log sub(*this, variant_ptr_and_end.first); - const uint8_t *variant_end = variant_ptr_and_end.second; - - bool first = true; - while (sub.sp < variant_end) { - out << (first ? "(" : ", "); - sub.walk(); - sub.align = true, first = false; - } - - if (!first) - out << ")"; -} - -void -log::walk_res2(const rust_fn *dtor, const uint8_t *end_sp) { - out << prefix << "res"; - - if (this->sp == end_sp) - return; - - out << "("; - - bool first = true; - while (sp != end_sp) { - if (!first) - out << ", "; - walk(); - align = true, first = false; - } - - out << ")"; -} - -} // end namespace shape - -extern "C" void -shape_cmp_type(int8_t *result, const type_desc *tydesc, - uint8_t *data_0, uint8_t *data_1, uint8_t cmp_type) { - rust_task *task = rust_get_current_task(); - shape::arena arena; - - shape::cmp cmp(task, true, tydesc->shape, tydesc->shape_tables, - data_0, data_1); - cmp.walk(); - - switch (cmp_type) { - case shape::CMP_EQ: *result = cmp.result == 0; break; - case shape::CMP_LT: *result = cmp.result < 0; break; - case shape::CMP_LE: *result = cmp.result <= 0; break; - } -} - -extern "C" rust_str * -shape_log_str(const type_desc *tydesc, uint8_t *data) { - rust_task *task = rust_get_current_task(); - - shape::arena arena; - - std::stringstream ss; - shape::log log(task, true, tydesc->shape, tydesc->shape_tables, - data, ss); - - log.walk(); - - int len = ss.str().length(); - return make_str(task->kernel, ss.str().c_str(), len, "log_str"); -} - -extern "C" void -shape_log_type(const type_desc *tydesc, uint8_t *data, uint32_t level) { - rust_task *task = rust_get_current_task(); - - shape::arena arena; - - std::stringstream ss; - shape::log log(task, true, tydesc->shape, tydesc->shape_tables, - data, ss); - - log.walk(); - - task->sched_loop->get_log().log(task, level, "%s", ss.str().c_str()); -} - -// -// Local Variables: -// mode: C++ -// fill-column: 78; -// indent-tabs-mode: nil -// c-basic-offset: 4 -// buffer-file-coding-system: utf-8-unix -// End: -// diff --git a/src/rt/rust_shape.h b/src/rt/rust_shape.h deleted file mode 100644 index fffbfad1d81..00000000000 --- a/src/rt/rust_shape.h +++ /dev/null @@ -1,1314 +0,0 @@ -// Functions that interpret the shape of a type to perform various low-level -// actions, such as copying, freeing, comparing, and so on. - -#ifndef RUST_SHAPE_H -#define RUST_SHAPE_H - -// Tell ISAAC to let go of max() and min() defines. -#undef max -#undef min - -#include <iostream> - -#include "rust_globals.h" -#include "rust_util.h" - -// ISAAC pollutes our namespace. -#undef align - -#define ARENA_SIZE 256 - -//#define DPRINT(fmt,...) fprintf(stderr, fmt, ##__VA_ARGS__) -//#define DPRINTCX(cx) shape::print::print_cx(cx) - -#define DPRINT(fmt,...) -#define DPRINTCX(cx) - - -namespace shape { - -typedef unsigned long tag_variant_t; -typedef unsigned long tag_align_t; - -// Constants - -const uint8_t SHAPE_U8 = 0u; -const uint8_t SHAPE_U16 = 1u; -const uint8_t SHAPE_U32 = 2u; -const uint8_t SHAPE_U64 = 3u; -const uint8_t SHAPE_I8 = 4u; -const uint8_t SHAPE_I16 = 5u; -const uint8_t SHAPE_I32 = 6u; -const uint8_t SHAPE_I64 = 7u; -const uint8_t SHAPE_F32 = 8u; -const uint8_t SHAPE_F64 = 9u; -const uint8_t SHAPE_BOX = 10u; -const uint8_t SHAPE_TAG = 12u; -const uint8_t SHAPE_STRUCT = 17u; -const uint8_t SHAPE_BOX_FN = 18u; -const uint8_t SHAPE_RES = 20u; -const uint8_t SHAPE_UNIQ = 22u; -const uint8_t SHAPE_UNIQ_FN = 25u; -const uint8_t SHAPE_STACK_FN = 26u; -const uint8_t SHAPE_BARE_FN = 27u; -const uint8_t SHAPE_TYDESC = 28u; -const uint8_t SHAPE_SEND_TYDESC = 29u; -const uint8_t SHAPE_RPTR = 31u; -const uint8_t SHAPE_FIXEDVEC = 32u; -const uint8_t SHAPE_SLICE = 33u; -const uint8_t SHAPE_UNBOXED_VEC = 34u; - -#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; - - -// Arenas; these functions must execute very quickly, so we use an arena -// instead of malloc or new. - -class arena { - uint8_t *ptr; - uint8_t data[ARENA_SIZE]; - -public: - arena() : ptr(data) {} - - template<typename T> - inline T *alloc(size_t count = 1) { - // FIXME: align (probably won't fix before #1498) - size_t sz = count * sizeof(T); - T *rv = (T *)ptr; - ptr += sz; - if (ptr > &data[ARENA_SIZE]) { - fprintf(stderr, "Arena space exhausted, sorry\n"); - abort(); - } - return rv; - } -}; - - -// Alignment inquiries -// -// We can't directly use __alignof__ everywhere because that returns the -// preferred alignment of the type, which is different from the ABI-mandated -// alignment of the type in some cases (e.g. doubles on x86). The latter is -// what actually gets used for struct elements. - -template<typename T> -inline size_t -rust_alignof() { -#ifdef _MSC_VER - return __alignof(T); -#else - return __alignof__(T); -#endif -} - -template<> -inline size_t -rust_alignof<double>() { - return 4; -} - -// Issue #2303 -// On 32-bit x86 the alignment of 64-bit ints in structures is 4 bytes -// Which is different from the preferred 8-byte alignment reported -// by __alignof__ (at least on gcc). -#ifndef __WIN32__ -#ifdef __i386__ -template<> -inline size_t -rust_alignof<uint64_t>() { - return 4; -} -#endif -#endif - - -// Utility classes - -struct size_align { - size_t size; - size_t alignment; - - size_align(size_t in_size = 0, size_t in_align = 1) : - size(in_size), alignment(in_align) {} - - bool is_set() const { return alignment != 0; } - - inline void set(size_t in_size, size_t in_align) { - size = in_size; - alignment = in_align; - } - - inline void add(const size_align &other) { - add(other.size, other.alignment); - } - - inline void add(size_t extra_size, size_t extra_align) { - size += extra_size; - alignment = std::max(alignment, extra_align); - } - - static inline size_align make(size_t in_size) { - size_align sa; - sa.size = sa.alignment = in_size; - return sa; - } - - static inline size_align make(size_t in_size, size_t in_align) { - size_align sa; - sa.size = in_size; - sa.alignment = in_align; - return sa; - } -}; - -struct tag_info { - uint16_t tag_id; // The tag ID. - const uint8_t *info_ptr; // Pointer to the info table. - uint16_t variant_count; // Number of variants in the tag. - const uint8_t *largest_variants_ptr; // Ptr to largest variants table. - size_align tag_sa; // Size and align of this tag. -}; - - -// Utility functions - -inline uint16_t -get_u16(const uint8_t *addr) { - return *reinterpret_cast<const uint16_t *>(addr); -} - -inline uint16_t -get_u16_bump(const uint8_t *&addr) { - uint16_t result = get_u16(addr); - addr += sizeof(uint16_t); - return result; -} - -template<typename T> -inline void -fmt_number(std::ostream &out, T n) { - out << n; -} - -// Override the character interpretation for these two. -template<> -inline void -fmt_number<uint8_t>(std::ostream &out, uint8_t n) { - out << (int)n; -} -template<> -inline void -fmt_number<int8_t>(std::ostream &out, int8_t n) { - out << (int)n; -} - - -// Contexts - -// The base context, an abstract class. We use the curiously recurring -// template pattern here to avoid virtual dispatch. -template<typename T> -class ctxt { -public: - const uint8_t *sp; // shape pointer - const rust_shape_tables *tables; - rust_task *task; - bool align; - - ctxt(rust_task *in_task, - bool in_align, - const uint8_t *in_sp, - const rust_shape_tables *in_tables) - : sp(in_sp), - tables(in_tables), - task(in_task), - align(in_align) {} - - template<typename U> - ctxt(const ctxt<U> &other, - const uint8_t *in_sp = NULL, - const rust_shape_tables *in_tables = NULL) - : sp(in_sp ? in_sp : other.sp), - tables(in_tables ? in_tables : other.tables), - task(other.task), - align(other.align) {} - - void walk(); - void walk_reset(); - - std::pair<const uint8_t *,const uint8_t *> - get_variant_sp(tag_info &info, tag_variant_t variant_id); - - const char * - get_variant_name(tag_info &info, tag_variant_t variant_id); - -protected: - inline uint8_t peek() { return *sp; } - - inline size_align get_size_align(const uint8_t *&addr); - -private: - void walk_vec0(); - void walk_unboxed_vec0(); - void walk_tag0(); - void walk_box0(); - void walk_uniq0(); - void walk_struct0(); - void walk_res0(); - void walk_rptr0(); - void walk_fixedvec0(); - void walk_slice0(); -}; - - -// Core Rust types - -struct rust_fn { - void (*code)(uint8_t *rv, rust_task *task, void *env, ...); - void *env; -}; - -// Traversals - -#define WALK_NUMBER(c_type) \ - static_cast<T *>(this)->template walk_number1<c_type>() -#define WALK_SIMPLE(method) static_cast<T *>(this)->method() - -template<typename T> -void -ctxt<T>::walk() { - char s = *sp++; - switch (s) { - case SHAPE_U8: WALK_NUMBER(uint8_t); break; - case SHAPE_U16: WALK_NUMBER(uint16_t); break; - case SHAPE_U32: WALK_NUMBER(uint32_t); break; - case SHAPE_U64: WALK_NUMBER(uint64_t); break; - case SHAPE_I8: WALK_NUMBER(int8_t); break; - case SHAPE_I16: WALK_NUMBER(int16_t); break; - case SHAPE_I32: WALK_NUMBER(int32_t); break; - case SHAPE_I64: WALK_NUMBER(int64_t); break; - case SHAPE_F32: WALK_NUMBER(float); break; - case SHAPE_F64: WALK_NUMBER(double); break; - case SHAPE_TAG: walk_tag0(); break; - case SHAPE_BOX: walk_box0(); break; - case SHAPE_STRUCT: walk_struct0(); break; - case SHAPE_RES: walk_res0(); break; - case SHAPE_UNIQ: walk_uniq0(); break; - case SHAPE_BOX_FN: - case SHAPE_UNIQ_FN: - case SHAPE_STACK_FN: - case SHAPE_BARE_FN: static_cast<T*>(this)->walk_fn1(s); break; - case SHAPE_TYDESC: - case SHAPE_SEND_TYDESC: static_cast<T*>(this)->walk_tydesc1(s); break; - case SHAPE_RPTR: walk_rptr0(); break; - case SHAPE_FIXEDVEC: walk_fixedvec0(); break; - case SHAPE_SLICE: walk_slice0(); break; - case SHAPE_UNBOXED_VEC: walk_unboxed_vec0(); break; - default: abort(); - } -} - -template<typename T> -void -ctxt<T>::walk_reset() { - const uint8_t *old_sp = sp; - walk(); - sp = old_sp; -} - -template<typename T> -size_align -ctxt<T>::get_size_align(const uint8_t *&addr) { - size_align result; - result.size = get_u16_bump(addr); - result.alignment = *addr++; - return result; -} - -// Returns a pointer to the beginning and a pointer to the end of the shape of -// the tag variant with the given ID. -template<typename T> -std::pair<const uint8_t *,const uint8_t *> -ctxt<T>::get_variant_sp(tag_info &tinfo, tag_variant_t variant_id) { - uint16_t variant_offset = get_u16(tinfo.info_ptr + - variant_id * sizeof(uint16_t)); - const uint8_t *variant_ptr = tables->tags + variant_offset; - uint16_t variant_len = get_u16_bump(variant_ptr); - const uint8_t *variant_end = variant_ptr + variant_len; - - return std::make_pair(variant_ptr, variant_end); -} - -template<typename T> -const char * -ctxt<T>::get_variant_name(tag_info &tinfo, tag_variant_t variant_id) { - std::pair<const uint8_t *,const uint8_t *> variant_ptr_and_end = - this->get_variant_sp(tinfo, variant_id); - // skip over the length to get the null-terminated string: - return (const char*)(variant_ptr_and_end.second + 2); -} - -template<typename T> -void -ctxt<T>::walk_vec0() { - bool is_pod = *sp++; - - uint16_t sp_size = get_u16_bump(sp); - const uint8_t *end_sp = sp + sp_size; - - static_cast<T *>(this)->walk_vec1(is_pod); - - sp = end_sp; -} - -template<typename T> -void -ctxt<T>::walk_unboxed_vec0() { - bool is_pod = *sp++; - - uint16_t sp_size = get_u16_bump(sp); - const uint8_t *end_sp = sp + sp_size; - - static_cast<T *>(this)->walk_unboxed_vec1(is_pod); - - sp = end_sp; -} - -template<typename T> -void -ctxt<T>::walk_tag0() { - tag_info tinfo; - tinfo.tag_id = get_u16_bump(sp); - - // Determine the info pointer. - uint16_t info_offset = get_u16(tables->tags + - tinfo.tag_id * sizeof(uint16_t)); - tinfo.info_ptr = tables->tags + info_offset; - - tinfo.variant_count = get_u16_bump(tinfo.info_ptr); - - // Determine the largest-variants pointer. - uint16_t largest_variants_offset = get_u16_bump(tinfo.info_ptr); - tinfo.largest_variants_ptr = tables->tags + largest_variants_offset; - - // Determine the size and alignment. - tinfo.tag_sa = get_size_align(tinfo.info_ptr); - - // Call to the implementation. - static_cast<T *>(this)->walk_tag1(tinfo); -} - -template<typename T> -void -ctxt<T>::walk_box0() { - static_cast<T *>(this)->walk_box1(); -} - -template<typename T> -void -ctxt<T>::walk_uniq0() { - uint16_t sp_size = get_u16_bump(sp); - const uint8_t *end_sp = sp + sp_size; - - static_cast<T *>(this)->walk_uniq1(); - - sp = end_sp; -} - -template<typename T> -void -ctxt<T>::walk_rptr0() { - uint16_t sp_size = get_u16_bump(sp); - const uint8_t *end_sp = sp + sp_size; - - static_cast<T *>(this)->walk_rptr1(); - - sp = end_sp; -} - -template<typename T> -void -ctxt<T>::walk_fixedvec0() { - uint16_t n_elts = get_u16_bump(sp); - bool is_pod = *sp++; - uint16_t sp_size = get_u16_bump(sp); - const uint8_t *end_sp = sp + sp_size; - - static_cast<T *>(this)->walk_fixedvec1(n_elts, is_pod); - - sp = end_sp; -} - -template<typename T> -void -ctxt<T>::walk_slice0() { - bool is_pod = *sp++; - bool is_str = *sp++; - uint16_t sp_size = get_u16_bump(sp); - const uint8_t *end_sp = sp + sp_size; - - static_cast<T *>(this)->walk_slice1(is_pod, is_str); - - sp = end_sp; -} - - -template<typename T> -void -ctxt<T>::walk_struct0() { - uint16_t sp_size = get_u16_bump(sp); - const uint8_t *end_sp = sp + sp_size; - - static_cast<T *>(this)->walk_struct1(end_sp); - - sp = end_sp; -} - -template<typename T> -void -ctxt<T>::walk_res0() { - uint16_t dtor_offset = get_u16_bump(sp); - const rust_fn **resources = - reinterpret_cast<const rust_fn **>(tables->resources); - const rust_fn *dtor = resources[dtor_offset]; - - uint16_t sp_size = get_u16_bump(sp); - const uint8_t *end_sp = sp + sp_size; - - static_cast<T *>(this)->walk_res1(dtor, end_sp); - - sp = end_sp; -} - -// A shape printer, useful for debugging - -class print : public ctxt<print> { -public: - template<typename T> - print(const ctxt<T> &other, - const uint8_t *in_sp = NULL, - const rust_shape_tables *in_tables = NULL) - : ctxt<print>(other, in_sp, in_tables) {} - - print(rust_task *in_task, - bool in_align, - const uint8_t *in_sp, - const rust_shape_tables *in_tables) - : ctxt<print>(in_task, in_align, in_sp, in_tables) {} - - void walk_tag1(tag_info &tinfo); - void walk_struct1(const uint8_t *end_sp); - void walk_res1(const rust_fn *dtor, const uint8_t *end_sp); - - void walk_vec1(bool is_pod) { - DPRINT("vec<"); walk(); DPRINT(">"); - } - void walk_unboxed_vec1(bool is_pod) { - DPRINT("unboxed_vec<"); walk(); DPRINT(">"); - } - void walk_uniq1() { - DPRINT("~<"); walk(); DPRINT(">"); - } - void walk_box1() { - DPRINT("@<"); walk(); DPRINT(">"); - } - void walk_rptr1() { - DPRINT("&<"); walk(); DPRINT(">"); - } - void walk_fixedvec1(uint16_t n_elts, bool is_pod) { - DPRINT("fixedvec<%u, ", n_elts); walk(); DPRINT(">"); - } - void walk_slice1(bool is_pod, bool is_str) { - DPRINT("slice<"); walk(); DPRINT(">"); - } - - void walk_fn1(char kind) { - switch(kind) { - case SHAPE_BARE_FN: DPRINT("fn"); break; - case SHAPE_BOX_FN: DPRINT("fn@"); break; - case SHAPE_UNIQ_FN: DPRINT("fn~"); break; - case SHAPE_STACK_FN: DPRINT("fn&"); break; - default: abort(); - } - } - void walk_trait1() { DPRINT("trait"); } - - void walk_tydesc1(char kind) { - switch(kind) { - case SHAPE_TYDESC: DPRINT("tydesc"); break; - case SHAPE_SEND_TYDESC: DPRINT("send-tydesc"); break; - default: abort(); - } - } - - template<typename T> - void walk_number1() {} - - template<typename T> - static void print_cx(const T *cx) { - print self(*cx); - self.align = false; - self.walk(); - } -}; - - -// -// Size-of (which also computes alignment). Be warned: this is an expensive -// operation. -// -// FIXME #2894: Maybe dynamic_size_of() should call into this somehow? -// - -class size_of : public ctxt<size_of> { -private: - size_align sa; - -public: - size_of(const size_of &other, - const uint8_t *in_sp = NULL, - const rust_shape_tables *in_tables = NULL) - : ctxt<size_of>(other, in_sp, in_tables) {} - - template<typename T> - size_of(const ctxt<T> &other, - const uint8_t *in_sp = NULL, - const rust_shape_tables *in_tables = NULL) - : ctxt<size_of>(other, in_sp, in_tables) {} - - void walk_tag1(tag_info &tinfo); - void walk_struct1(const uint8_t *end_sp); - - void walk_uniq1() { sa.set(sizeof(void *), sizeof(void *)); } - void walk_rptr1() { sa.set(sizeof(void *), sizeof(void *)); } - void walk_slice1(bool,bool) - { sa.set(sizeof(void *)*2, sizeof(void *)); } - void walk_box1() { sa.set(sizeof(void *), sizeof(void *)); } - void walk_fn1(char) { sa.set(sizeof(void *)*2, sizeof(void *)); } - void walk_trait1() { sa.set(sizeof(void *), sizeof(void *)); } - void walk_tydesc1(char) { sa.set(sizeof(void *), sizeof(void *)); } - void walk_closure1(); - - void walk_vec1(bool is_pod) { - sa.set(sizeof(void *), sizeof(void *)); - } - - void walk_unboxed_vec1(bool is_pod) { - assert(false && - "trying to compute size of dynamically sized unboxed vector"); - } - - void walk_res1(const rust_fn *dtor, const uint8_t *end_sp) { - abort(); // FIXME #2895 - } - - void walk_fixedvec1(uint16_t n_elts, bool is_pod) { - size_of sub(*this); - sub.walk(); - sa.set(sub.sa.size * n_elts, sub.sa.alignment); - } - - template<typename T> - void walk_number1() { sa.set(sizeof(T), rust_alignof<T>()); } - - void compute_tag_size(tag_info &tinfo); - - template<typename T> - static void compute_tag_size(const ctxt<T> &other_cx, tag_info &tinfo) { - size_of cx(other_cx); - cx.compute_tag_size(tinfo); - } - - template<typename T> - static size_align get(const ctxt<T> &other_cx, unsigned back_up = 0) { - size_of cx(other_cx, other_cx.sp - back_up); - cx.align = false; - cx.walk(); - assert(cx.sa.alignment > 0); - return cx.sa; - } -}; - - -// Pointer wrappers for data traversals - -class ptr { -private: - uint8_t *p; - -public: - template<typename T> - struct data { typedef T t; }; - - ptr() : p(NULL) {} - explicit ptr(uint8_t *in_p) : p(in_p) {} - explicit ptr(uintptr_t in_p) : p((uint8_t *)in_p) {} - - inline ptr operator+(const size_t amount) const { - return make(p + amount); - } - inline ptr &operator+=(const size_t amount) { p += amount; return *this; } - inline bool operator<(const ptr other) { return p < other.p; } - inline ptr operator++() { ptr rv(*this); p++; return rv; } - inline uint8_t operator*() { return *p; } - - template<typename T> - inline operator T *() { return (T *)p; } - - inline operator bool() const { return p != NULL; } - inline operator uintptr_t() const { return (uintptr_t)p; } - - inline const type_desc *box_body_td() const { - rust_opaque_box *box = *reinterpret_cast<rust_opaque_box**>(p); - assert(box->ref_count >= 1); - return box->td; - } - - inline const type_desc *uniq_body_td() const { - rust_opaque_box *box = *reinterpret_cast<rust_opaque_box**>(p); - return box->td; - } - - inline ptr box_body() const { - rust_opaque_box *box = *reinterpret_cast<rust_opaque_box**>(p); - return make((uint8_t*)::box_body(box)); - } - - static inline ptr make(uint8_t *in_p) { - ptr self(in_p); - return self; - } -}; - -template<typename T> -static inline T -bump_dp(ptr &dp) { - T x = *((T *)dp); - dp += sizeof(T); - return x; -} - -template<typename T> -static inline T -get_dp(ptr dp) { - return *((T *)dp); -} - - -// Pointer pairs for structural comparison - -template<typename T> -class data_pair { -public: - T fst, snd; - - data_pair() {} - data_pair(T &in_fst, T &in_snd) : fst(in_fst), snd(in_snd) {} - - inline void operator=(const T rhs) { fst = snd = rhs; } - - static data_pair<T> make(T &fst, T &snd) { - data_pair<T> data(fst, snd); - return data; - } -}; - -class ptr_pair { -public: - uint8_t *fst, *snd; - - template<typename T> - struct data { typedef data_pair<T> t; }; - - ptr_pair() : fst(NULL), snd(NULL) {} - ptr_pair(uint8_t *in_fst, uint8_t *in_snd) : fst(in_fst), snd(in_snd) {} - ptr_pair(data_pair<uint8_t *> &other) : fst(other.fst), snd(other.snd) {} - - inline void operator=(uint8_t *rhs) { fst = snd = rhs; } - - inline operator bool() const { return fst != NULL && snd != NULL; } - - inline ptr_pair operator+(size_t n) const { - return make(fst + n, snd + n); - } - - inline ptr_pair operator+=(size_t n) { - fst += n; snd += n; - return *this; - } - - inline ptr_pair operator-(size_t n) const { - return make(fst - n, snd - n); - } - - inline bool operator<(const ptr_pair &other) const { - return fst < other.fst && snd < other.snd; - } - - static inline ptr_pair make(uint8_t *fst, uint8_t *snd) { - ptr_pair self(fst, snd); - return self; - } - - static inline ptr_pair make(const data_pair<uint8_t *> &pair) { - ptr_pair self(pair.fst, pair.snd); - return self; - } - - inline const type_desc *box_body_td() const { - // Here we assume that the two ptrs are both boxes with - // equivalent type descriptors. This is safe because we only - // use ptr_pair in the cmp glue, and we only use the cmp glue - // when rust guarantees us that the boxes are of the same - // type. As box types are not opaque to Rust, it is in a - // position to make this determination. - rust_opaque_box *box_fst = *reinterpret_cast<rust_opaque_box**>(fst); - assert(box_fst->ref_count >= 1); - return box_fst->td; - } - - inline const type_desc *uniq_body_td() const { - rust_opaque_box *box_fst = *reinterpret_cast<rust_opaque_box**>(fst); - return box_fst->td; - } - - inline ptr_pair box_body() const { - rust_opaque_box *box_fst = *reinterpret_cast<rust_opaque_box**>(fst); - rust_opaque_box *box_snd = *reinterpret_cast<rust_opaque_box**>(snd); - return make((uint8_t*)::box_body(box_fst), - (uint8_t*)::box_body(box_snd)); - } -}; - -// NB: This function does not align. -template<typename T> -inline data_pair<T> -bump_dp(ptr_pair &ptr) { - data_pair<T> data(*reinterpret_cast<T *>(ptr.fst), - *reinterpret_cast<T *>(ptr.snd)); - ptr += sizeof(T); - return data; -} - -template<typename T> -inline data_pair<T> -get_dp(ptr_pair &ptr) { - data_pair<T> data(*reinterpret_cast<T *>(ptr.fst), - *reinterpret_cast<T *>(ptr.snd)); - return data; -} - -} // end namespace shape - - -inline shape::ptr_pair -align_to(const shape::ptr_pair &pair, size_t n) { - return shape::ptr_pair::make(align_to(pair.fst, n), - align_to(pair.snd, n)); -} - - -namespace shape { - -// An abstract class (again using the curiously recurring template pattern) -// for methods that actually manipulate the data involved. - -#define ALIGN_TO(alignment) \ - if (this->align) { \ - dp = align_to(dp, (alignment)); \ - if (this->end_dp && !(dp < this->end_dp)) \ - return; \ - } - -#define DATA_SIMPLE(ty, call) \ - ALIGN_TO(rust_alignof<ty>()); \ - U end_dp = dp + sizeof(ty); \ - static_cast<T *>(this)->call; \ - dp = end_dp; - -template<typename T,typename U> -class data : public ctxt< data<T,U> > { -public: - U dp; - -protected: - U end_dp; - - void walk_box_contents1(); - void walk_uniq_contents1(); - void walk_rptr_contents1(); - void walk_fn_contents1(); - void walk_trait_contents1(); - void walk_variant1(tag_info &tinfo, tag_variant_t variant); - - static std::pair<uint8_t *,uint8_t *> get_vec_data_range(ptr dp); - static std::pair<ptr_pair,ptr_pair> get_vec_data_range(ptr_pair &dp); - - static std::pair<uint8_t *,uint8_t *> get_unboxed_vec_data_range(ptr dp); - static std::pair<ptr_pair,ptr_pair> - get_unboxed_vec_data_range(ptr_pair &dp); - static ptr get_unboxed_vec_end(ptr dp); - static ptr_pair get_unboxed_vec_end(ptr_pair &dp); - - static std::pair<uint8_t *,uint8_t *> get_slice_data_range(bool is_str, - ptr dp); - static std::pair<ptr_pair,ptr_pair> get_slice_data_range(bool is_str, - ptr_pair &dp); - - static std::pair<uint8_t *,uint8_t *> - get_fixedvec_data_range(uint16_t n_elts, size_t elt_sz, ptr dp); - static std::pair<ptr_pair,ptr_pair> - get_fixedvec_data_range(uint16_t n_elts, size_t elt_sz, ptr_pair &dp); - -public: - data(rust_task *in_task, - bool in_align, - const uint8_t *in_sp, - const rust_shape_tables *in_tables, - U const &in_dp) - : ctxt< data<T,U> >(in_task, in_align, in_sp, in_tables), - dp(in_dp), - end_dp() {} - - void walk_tag1(tag_info &tinfo); - - void walk_struct1(const uint8_t *end_sp) { - // FIXME (probably won't fix before #1498): shouldn't we be aligning - // to the first element here? - static_cast<T *>(this)->walk_struct2(end_sp); - } - - void walk_vec1(bool is_pod) { - DATA_SIMPLE(void *, walk_vec2(is_pod)); - } - - void walk_unboxed_vec1(bool is_pod) { - // align? - U next_dp = get_unboxed_vec_end(dp); - static_cast<T *>(this)->walk_unboxed_vec2(is_pod); - dp = next_dp; - } - - void walk_slice1(bool is_pod, bool is_str) { - DATA_SIMPLE(void *, walk_slice2(is_pod, is_str)); - } - - void walk_fixedvec1(uint16_t n_elts, bool is_pod) { - size_align sa = size_of::get(*this); - ALIGN_TO(sa.alignment); - U next_dp = dp + (n_elts * sa.size); - static_cast<T *>(this)->walk_fixedvec2(n_elts, sa.size, is_pod); - dp = next_dp; - } - - void walk_box1() { DATA_SIMPLE(void *, walk_box2()); } - - void walk_uniq1() { DATA_SIMPLE(void *, walk_uniq2()); } - - void walk_rptr1() { DATA_SIMPLE(void *, walk_rptr2()); } - - void walk_fn1(char code) { - ALIGN_TO(rust_alignof<void *>()); - U next_dp = dp + sizeof(void *) * 2; - static_cast<T *>(this)->walk_fn2(code); - dp = next_dp; - } - - void walk_trait1() { - ALIGN_TO(rust_alignof<void *>()); - U next_dp = dp + sizeof(void *); - static_cast<T *>(this)->walk_trait2(); - dp = next_dp; - } - - void walk_tydesc1(char kind) { - ALIGN_TO(rust_alignof<void *>()); - U next_dp = dp + sizeof(void *); - static_cast<T *>(this)->walk_tydesc2(kind); - dp = next_dp; - } - - void walk_res1(const rust_fn *dtor, const uint8_t *end_sp) { - // Delegate to the implementation. - static_cast<T *>(this)->walk_res2(dtor, end_sp); - } - - template<typename WN> - void walk_number1() { - //DATA_SIMPLE(W, walk_number2<W>()); - ALIGN_TO(rust_alignof<WN>()); - U end_dp = dp + sizeof(WN); - T* t = static_cast<T *>(this); - t->template walk_number2<WN>(); - dp = end_dp; - } -}; - -template<typename T,typename U> -void -data<T,U>::walk_box_contents1() { - const type_desc *body_td = dp.box_body_td(); - if (body_td) { - U body_dp(dp.box_body()); - arena arena; - T sub(*static_cast<T *>(this), body_td->shape, - body_td->shape_tables, body_dp); - sub.align = true; - static_cast<T *>(this)->walk_box_contents2(sub); - } -} - -template<typename T,typename U> -void -data<T,U>::walk_uniq_contents1() { - const type_desc *body_td = dp.uniq_body_td(); - if (body_td) { - U body_dp(dp.box_body()); - arena arena; - T sub(*static_cast<T *>(this), /*body_td->shape,*/ this->sp, - body_td->shape_tables, body_dp); - sub.align = true; - static_cast<T *>(this)->walk_uniq_contents2(sub); - } -} - -template<typename T,typename U> -void -data<T,U>::walk_rptr_contents1() { - typename U::template data<uint8_t *>::t box_ptr = bump_dp<uint8_t *>(dp); - U data_ptr(box_ptr); - T sub(*static_cast<T *>(this), data_ptr); - static_cast<T *>(this)->walk_rptr_contents2(sub); -} - -template<typename T,typename U> -void -data<T,U>::walk_variant1(tag_info &tinfo, tag_variant_t variant_id) { - std::pair<const uint8_t *,const uint8_t *> variant_ptr_and_end = - this->get_variant_sp(tinfo, variant_id); - static_cast<T *>(this)->walk_variant2(tinfo, variant_id, - variant_ptr_and_end); -} - -template<typename T,typename U> -std::pair<uint8_t *,uint8_t *> -data<T,U>::get_vec_data_range(ptr dp) { - rust_vec_box* ptr = bump_dp<rust_vec_box*>(dp); - uint8_t* data = &ptr->body.data[0]; - return std::make_pair(data, data + ptr->body.fill); -} - -template<typename T,typename U> -std::pair<ptr_pair,ptr_pair> -data<T,U>::get_vec_data_range(ptr_pair &dp) { - std::pair<uint8_t *,uint8_t *> fst = - get_vec_data_range(shape::ptr(dp.fst)); - std::pair<uint8_t *,uint8_t *> snd = - get_vec_data_range(shape::ptr(dp.snd)); - ptr_pair start(fst.first, snd.first); - ptr_pair end(fst.second, snd.second); - return std::make_pair(start, end); -} - -template<typename T,typename U> -std::pair<uint8_t *,uint8_t *> -data<T,U>::get_unboxed_vec_data_range(ptr dp) { - rust_vec* ptr = (rust_vec*)dp; - uint8_t* data = &ptr->data[0]; - return std::make_pair(data, data + ptr->fill); -} - -template<typename T,typename U> -std::pair<ptr_pair,ptr_pair> -data<T,U>::get_unboxed_vec_data_range(ptr_pair &dp) { - std::pair<uint8_t *,uint8_t *> fst = - get_unboxed_vec_data_range(shape::ptr(dp.fst)); - std::pair<uint8_t *,uint8_t *> snd = - get_unboxed_vec_data_range(shape::ptr(dp.snd)); - ptr_pair start(fst.first, snd.first); - ptr_pair end(fst.second, snd.second); - return std::make_pair(start, end); -} - -template<typename T,typename U> -ptr data<T,U>::get_unboxed_vec_end(ptr dp) { - rust_vec* ptr = (rust_vec*)dp; - return dp + sizeof(rust_vec) + ptr->fill; -} - -template<typename T,typename U> -ptr_pair data<T,U>::get_unboxed_vec_end(ptr_pair &dp) { - return ptr_pair(get_unboxed_vec_end(ptr(dp.fst)), - get_unboxed_vec_end(ptr(dp.snd))); -} - -template<typename T,typename U> -std::pair<uint8_t *,uint8_t *> -data<T,U>::get_slice_data_range(bool is_str, ptr dp) { - uint8_t* ptr = bump_dp<uint8_t*>(dp); - size_t len = bump_dp<size_t>(dp); - if (is_str) len--; - return std::make_pair(ptr, ptr + len); -} - -template<typename T,typename U> -std::pair<ptr_pair,ptr_pair> -data<T,U>::get_slice_data_range(bool is_str, ptr_pair &dp) { - std::pair<uint8_t *,uint8_t *> fst = - get_slice_data_range(is_str, shape::ptr(dp.fst)); - std::pair<uint8_t *,uint8_t *> snd = - get_slice_data_range(is_str, shape::ptr(dp.snd)); - ptr_pair start(fst.first, snd.first); - ptr_pair end(fst.second, snd.second); - return std::make_pair(start, end); -} - -template<typename T,typename U> -std::pair<uint8_t *,uint8_t *> -data<T,U>::get_fixedvec_data_range(uint16_t n_elts, size_t elt_sz, ptr dp) { - uint8_t* ptr = (uint8_t*)(dp); - return std::make_pair(ptr, ptr + (((size_t)n_elts) * elt_sz)); -} - -template<typename T,typename U> -std::pair<ptr_pair,ptr_pair> -data<T,U>::get_fixedvec_data_range(uint16_t n_elts, size_t elt_sz, - ptr_pair &dp) { - std::pair<uint8_t *,uint8_t *> fst = - get_fixedvec_data_range(n_elts, elt_sz, shape::ptr(dp.fst)); - std::pair<uint8_t *,uint8_t *> snd = - get_fixedvec_data_range(n_elts, elt_sz, shape::ptr(dp.snd)); - ptr_pair start(fst.first, snd.first); - ptr_pair end(fst.second, snd.second); - return std::make_pair(start, end); -} - - -template<typename T,typename U> -void -data<T,U>::walk_tag1(tag_info &tinfo) { - size_of::compute_tag_size(*this, tinfo); - - if (tinfo.variant_count > 1) - ALIGN_TO(rust_alignof<tag_align_t>()); - - U end_dp = dp + tinfo.tag_sa.size; - - typename U::template data<tag_variant_t>::t tag_variant; - if (tinfo.variant_count > 1) - tag_variant = bump_dp<tag_variant_t>(dp); - else - tag_variant = 0; - - static_cast<T *>(this)->walk_tag2(tinfo, tag_variant); - - dp = end_dp; -} - -template<typename T,typename U> -void - data<T,U>::walk_fn_contents1() { - fn_env_pair pair = bump_dp<fn_env_pair>(dp); - if (!pair.env) - return; - - arena arena; - const type_desc *closure_td = pair.env->td; - ptr closure_dp((uintptr_t)box_body(pair.env)); - T sub(*static_cast<T *>(this), closure_td->shape, - closure_td->shape_tables, closure_dp); - sub.align = true; - - sub.walk(); -} - -template<typename T,typename U> -void -data<T,U>::walk_trait_contents1() { - walk_box_contents1(); -} - -// Polymorphic logging, for convenience - -class log : public data<log,ptr> { - friend class data<log,ptr>; - -private: - std::ostream &out; - const char *prefix; - bool in_string; - - log(log &other, - const uint8_t *in_sp, - const rust_shape_tables *in_tables = NULL) - : data<log,ptr>(other.task, - other.align, - in_sp, - in_tables ? in_tables : other.tables, - other.dp), - out(other.out), - prefix("") {} - - log(log &other, - const uint8_t *in_sp, - const rust_shape_tables *in_tables, - ptr in_dp) - : data<log,ptr>(other.task, - other.align, - in_sp, - in_tables, - in_dp), - out(other.out), - prefix("") {} - - log(log &other, ptr in_dp) - : data<log,ptr>(other.task, - other.align, - other.sp, - other.tables, - in_dp), - out(other.out), - prefix("") {} - - void walk_vec2(bool is_pod) { - if (!get_dp<void *>(dp)) - out << prefix << "(null)"; - else - walk_vec2(is_pod, get_vec_data_range(dp)); - } - - void walk_unboxed_vec2(bool is_pod) { - walk_vec2(is_pod, get_unboxed_vec_data_range(dp)); - } - - void walk_slice2(bool is_pod, bool is_str) { - walk_vec2(is_pod, get_slice_data_range(is_str, dp)); - out << "/&"; - } - - void walk_fixedvec2(uint16_t n_elts, size_t elt_sz, bool is_pod) { - walk_vec2(is_pod, get_fixedvec_data_range(n_elts, elt_sz, dp)); - out << "/" << n_elts; - } - - void walk_tag2(tag_info &tinfo, tag_variant_t tag_variant) { - // out << prefix << "tag" << tag_variant; - out << prefix << get_variant_name(tinfo, tag_variant); - data<log,ptr>::walk_variant1(tinfo, tag_variant); - } - - void walk_box2() { - out << prefix << "@"; - prefix = ""; - data<log,ptr>::walk_box_contents1(); - } - - void walk_uniq2() { - out << prefix << "~"; - prefix = ""; - data<log,ptr>::walk_uniq_contents1(); - } - - void walk_rptr2() { - out << prefix << "&"; - prefix = ""; - data<log,ptr>::walk_rptr_contents1(); - } - - void walk_fn2(char kind) { - out << prefix << "fn"; - prefix = ""; - data<log,ptr>::walk_fn_contents1(); - } - - void walk_trait2() { - out << prefix << "trait("; - prefix = ""; - data<log,ptr>::walk_trait_contents1(); - out << prefix << ")"; - } - - void walk_tydesc2(char kind) { - out << prefix << "tydesc"; - } - - void walk_subcontext2(log &sub) { sub.walk(); } - - void walk_box_contents2(log &sub) { - out << prefix; - rust_opaque_box *box_ptr = *(rust_opaque_box **) dp; - if (!box_ptr) { - out << "(null)"; - } else { - sub.align = true; - sub.walk(); - } - } - - void walk_uniq_contents2(log &sub) { - out << prefix; - sub.align = true; - sub.walk(); - } - - void walk_rptr_contents2(log &sub) { - out << prefix; - sub.align = true; - sub.walk(); - } - - void walk_struct2(const uint8_t *end_sp); - void walk_vec2(bool is_pod, const std::pair<ptr,ptr> &data); - void walk_slice2(bool is_pod, const std::pair<ptr,ptr> &data); - void walk_variant2(tag_info &tinfo, - tag_variant_t variant_id, - const std::pair<const uint8_t *,const uint8_t *> - variant_ptr_and_end); - void walk_string2(const std::pair<ptr,ptr> &data); - void walk_res2(const rust_fn *dtor, const uint8_t *end_sp); - - template<typename T> - inline void walk_number2() { - out << prefix; - fmt_number(out, get_dp<T>(dp)); - } - -public: - log(rust_task *in_task, - bool in_align, - const uint8_t *in_sp, - const rust_shape_tables *in_tables, - uint8_t *in_data, - std::ostream &in_out) - : data<log,ptr>(in_task, in_align, in_sp, in_tables, - ptr(in_data)), - out(in_out), - prefix("") {} -}; - -} // end namespace shape - -#endif - -// -// Local Variables: -// mode: C++ -// fill-column: 78; -// indent-tabs-mode: nil -// c-basic-offset: 4 -// buffer-file-coding-system: utf-8-unix -// End: -// diff --git a/src/rt/rust_type.h b/src/rt/rust_type.h index 036485825f1..9612c0dc409 100644 --- a/src/rt/rust_type.h +++ b/src/rt/rust_type.h @@ -17,11 +17,6 @@ struct type_desc; typedef void CDECL (glue_fn)(void *, void *, const type_desc **, void *); -struct rust_shape_tables { - uint8_t *tags; - uint8_t *resources; -}; - // Corresponds to the boxed data in the @ region. The body follows the // header; you can obtain a ptr via box_body() below. struct rust_opaque_box { @@ -52,8 +47,8 @@ struct type_desc { glue_fn *drop_glue; glue_fn *free_glue; glue_fn *visit_glue; - const uint8_t *shape; - const rust_shape_tables *shape_tables; + const uint8_t *unused; + const uint8_t *unused2; }; extern "C" type_desc *rust_clone_type_desc(type_desc*); diff --git a/src/rt/rust_upcall.cpp b/src/rt/rust_upcall.cpp index afb62d52be7..0a9f0647789 100644 --- a/src/rt/rust_upcall.cpp +++ b/src/rt/rust_upcall.cpp @@ -301,12 +301,8 @@ rust_upcall_free(void* ptr) { extern "C" CDECL void upcall_validate_box(rust_opaque_box* ptr) { - if (ptr) { - assert(ptr->ref_count > 0); - assert(ptr->td != NULL); - assert(ptr->td->align <= 8); - assert(ptr->td->size <= 4096); // might not really be true... - } + // XXX: Remove after snapshot + abort(); } /**********************************************************************/ @@ -365,52 +361,10 @@ upcall_rust_personality(int version, return args.retval; } -extern "C" void -shape_cmp_type(int8_t *result, const type_desc *tydesc, - uint8_t *data_0, uint8_t *data_1, uint8_t cmp_type); - -struct s_cmp_type_args { - int8_t *result; - const type_desc *tydesc; - uint8_t *data_0; - uint8_t *data_1; - uint8_t cmp_type; -}; - -extern "C" void -upcall_s_cmp_type(s_cmp_type_args *args) { - shape_cmp_type(args->result, args->tydesc, - args->data_0, args->data_1, args->cmp_type); -} - -extern "C" void -upcall_cmp_type(int8_t *result, const type_desc *tydesc, - uint8_t *data_0, uint8_t *data_1, uint8_t cmp_type) { - rust_task *task = rust_get_current_task(); - s_cmp_type_args args = {result, tydesc, - data_0, data_1, cmp_type}; - UPCALL_SWITCH_STACK(task, &args, upcall_s_cmp_type); -} - -extern "C" void -shape_log_type(const type_desc *tydesc, uint8_t *data, uint32_t level); - -struct s_log_type_args { - const type_desc *tydesc; - uint8_t *data; - uint32_t level; -}; - -extern "C" void -upcall_s_log_type(s_log_type_args *args) { - shape_log_type(args->tydesc, args->data, args->level); -} - extern "C" void upcall_log_type(const type_desc *tydesc, uint8_t *data, uint32_t level) { - rust_task *task = rust_get_current_task(); - s_log_type_args args = {tydesc, data, level}; - UPCALL_SWITCH_STACK(task, &args, upcall_s_log_type); + // XXX: Remove after snapshot + abort(); } // NB: This needs to be blazing fast. Don't switch stacks diff --git a/src/rt/rust_util.cpp b/src/rt/rust_util.cpp index cd765184c1e..60e6cc3d842 100644 --- a/src/rt/rust_util.cpp +++ b/src/rt/rust_util.cpp @@ -1,19 +1,9 @@ #include "rust_type.h" -#include "rust_shape.h" // A hardcoded type descriptor for strings, since the runtime needs to // be able to create them. -struct rust_shape_tables empty_shape_tables; - -uint8_t str_body_shape[] = { - shape::SHAPE_UNBOXED_VEC, - 0x1, // is_pod - 0x1, 0x0, // size field: 1 - shape::SHAPE_U8 -}; - struct type_desc str_body_tydesc = { 1, // size 1, // align @@ -21,8 +11,8 @@ struct type_desc str_body_tydesc = { NULL, // drop_glue NULL, // free_glue NULL, // visit_glue - str_body_shape, // shape - &empty_shape_tables, // shape_tables + NULL, // shape + NULL, // shape_tables }; // diff --git a/src/rt/rustrt.def.in b/src/rt/rustrt.def.in index 8dac7d515b3..020008c3842 100644 --- a/src/rt/rustrt.def.in +++ b/src/rt/rustrt.def.in @@ -64,14 +64,12 @@ rust_get_stack_segment rust_task_weaken rust_task_unweaken rust_log_str -shape_log_str start_task vec_reserve_shared_actual vec_reserve_shared task_clear_event_reject task_wait_event task_signal_event -upcall_cmp_type upcall_fail upcall_trace upcall_free