diff --git a/src/Makefile b/src/Makefile index c1e7ce41959..33f10b3936e 100644 --- a/src/Makefile +++ b/src/Makefile @@ -426,6 +426,7 @@ TEST_XFAILS_LLVM := $(addprefix test/run-pass/, \ lazy-and-or.rs \ lazy-init.rs \ lazychan.rs \ + lib-deque.rs \ lib-rand.rs \ linear-for-loop.rs \ list.rs \ diff --git a/src/boot/me/semant.ml b/src/boot/me/semant.ml index 16331e3611b..bcaec2b4a39 100644 --- a/src/boot/me/semant.ml +++ b/src/boot/me/semant.ml @@ -1061,6 +1061,23 @@ let rec simplified_ty (t:Ast.ty) : Ast.ty = | t -> t ;; +let rec innermost_box_ty (t:Ast.ty) : Ast.ty = + match strip_mutable_or_constrained_ty t with + Ast.TY_box t -> innermost_box_ty t + | _ -> t +;; + +let simplified_ty_innermost_was_mutable (t:Ast.ty) : Ast.ty * bool = + let rec simplify_innermost t = + match t with + Ast.TY_mutable t -> (fst (simplify_innermost t), true) + | Ast.TY_constrained (t, _) -> simplify_innermost t + | _ -> (t, false) + in + let t = innermost_box_ty t in + simplify_innermost t +;; + let rec project_type (base_ty:Ast.ty) (comp:Ast.lval_component) diff --git a/src/boot/me/trans.ml b/src/boot/me/trans.ml index 55ccadf77ce..06f04a3a489 100644 --- a/src/boot/me/trans.ml +++ b/src/boot/me/trans.ml @@ -1103,6 +1103,7 @@ let trans_visitor (t:Ast.ty) (sz:int64) (align:int64) + (force_stateful:bool) : Il.operand = trans_crate_rel_data_operand (DATA_tydesc t) @@ -1112,7 +1113,9 @@ let trans_visitor let fix fixup = fixup_rel_word tydesc_fixup fixup in - let is_stateful = if type_has_state t then 1L else 0L in + let is_stateful = + if (force_stateful || type_has_state t) then 1L else 0L + in log cx "tydesc for %a has sz=%Ld, align=%Ld, is_stateful=%Ld" Ast.sprintf_ty t sz align is_stateful; Asm.DEF @@ -2343,11 +2346,15 @@ let trans_visitor dst_cell dst_ty src_cell src_ty None - and get_dynamic_tydesc (idopt:node_id option) (t:Ast.ty) : Il.cell = + and get_dynamic_tydesc + (idopt:node_id option) + (t:Ast.ty) + (force_stateful:bool) + : Il.cell = let td = next_vreg_cell Il.voidptr_t in let root_desc = Il.Cell (crate_rel_to_ptr - (get_static_tydesc idopt t 0L 0L) + (get_static_tydesc idopt t 0L 0L force_stateful) (tydesc_rty abi)) in let (t, param_descs) = linearize_ty_params t in @@ -2378,15 +2385,17 @@ let trans_visitor and get_tydesc (idopt:node_id option) (ty:Ast.ty) : Il.cell = log cx "getting tydesc for %a" Ast.sprintf_ty ty; - match simplified_ty ty with + let (ty, mut) = simplified_ty_innermost_was_mutable ty in + match ty with Ast.TY_param (idx, _) -> (get_ty_param_in_current_frame idx) | t when has_parametric_types t -> - (get_dynamic_tydesc idopt t) + (get_dynamic_tydesc idopt t mut) | _ -> (crate_rel_to_ptr (get_static_tydesc idopt ty (ty_sz abi ty) - (ty_align abi ty)) + (ty_align abi ty) + mut) (tydesc_rty abi)) and box_rc_cell (cell:Il.cell) : Il.cell = diff --git a/src/lib/deque.rs b/src/lib/deque.rs index 699b3f0da08..24a03ed00b2 100644 --- a/src/lib/deque.rs +++ b/src/lib/deque.rs @@ -17,6 +17,8 @@ type t[T] = obj { fn peek_front() -> T; fn peek_back() -> T; + + fn get(int i) -> T; }; fn create[T]() -> t[T] { @@ -128,6 +130,11 @@ fn create[T]() -> t[T] { fn peek_back() -> T { ret get[T](elts, hi); } + + fn get(int i) -> T { + let uint idx = (lo + (i as uint)) % _vec.len[cell[T]](elts); + ret get[T](elts, idx); + } } let vec[cell[T]] v = _vec.init_elt[cell[T]](util.none[T](), diff --git a/src/rt/rust_crate_cache.cpp b/src/rt/rust_crate_cache.cpp index 650e3bb1ef3..c5076639e9a 100644 --- a/src/rt/rust_crate_cache.cpp +++ b/src/rt/rust_crate_cache.cpp @@ -216,6 +216,7 @@ rust_crate_cache::get_type_desc(size_t size, "rust_crate_cache::descs[%" PRIdPTR "] = 0x%" PRIxPTR, i, descs[i]); td->descs[i] = descs[i]; + td->is_stateful |= descs[i]->is_stateful; } adjust_disp(td->copy_glue_off, descs[0], td); adjust_disp(td->drop_glue_off, descs[0], td); diff --git a/src/rt/rust_upcall.cpp b/src/rt/rust_upcall.cpp index ff6874e4f48..8ce40b576cf 100644 --- a/src/rt/rust_upcall.cpp +++ b/src/rt/rust_upcall.cpp @@ -499,8 +499,13 @@ extern "C" CDECL uintptr_t upcall_require_c_sym(rust_task *task, } extern "C" CDECL type_desc * -upcall_get_type_desc(rust_task *task, rust_crate const *curr_crate, - size_t size, size_t align, size_t n_descs, type_desc const **descs) { +upcall_get_type_desc(rust_task *task, + rust_crate const *curr_crate, + size_t size, + size_t align, + size_t n_descs, + type_desc const **descs) +{ LOG_UPCALL_ENTRY(task); task->log(rust_log::UPCALL | rust_log::CACHE, "upcall get_type_desc with size=%" PRIdPTR diff --git a/src/test/run-pass/lib-deque.rs b/src/test/run-pass/lib-deque.rs new file mode 100644 index 00000000000..244092da79c --- /dev/null +++ b/src/test/run-pass/lib-deque.rs @@ -0,0 +1,17 @@ +// -*- rust -*- + +use std; +import std.deque; + +fn main() { + let deque.t[int] d1 = deque.create[int](); + check (d1.size() == 0u); + d1.add_front(17); + d1.add_front(42); + d1.add_back(137); + check (d1.size() == 3u); + d1.add_back(137); + check (d1.size() == 4u); + /* FIXME (issue #133): We should check that the numbers come back + * to us correctly once the deque stops zeroing them out. */ +}