2 import lib::llvm::llvm::ValueRef;
3 import trans_common::*;
19 export trans_uniq, make_free_glue, type_is_unique_box, copy_val,
22 pure fn type_is_unique_box(bcx: @block_ctxt, ty: ty::t) -> bool {
24 ty::type_is_unique_box(bcx_tcx(bcx), ty)
28 fn trans_uniq(cx: @block_ctxt, contents: @ast::expr,
29 node_id: ast::node_id) -> result {
32 let lv = trans_lval(bcx, contents);
35 let uniq_ty = node_id_type(bcx_ccx(cx), node_id);
36 check type_is_unique_box(bcx, uniq_ty);
37 let content_ty = content_ty(bcx, uniq_ty);
38 let {bcx, val: llptr} = alloc_uniq(bcx, uniq_ty);
40 add_clean_temp(bcx, llptr, uniq_ty);
42 bcx = move_val_if_temp(bcx, INIT, llptr, lv,
48 fn alloc_uniq(cx: @block_ctxt, uniq_ty: ty::t)
49 : type_is_unique_box(cx, uniq_ty) -> result {
52 let contents_ty = content_ty(bcx, uniq_ty);
53 let r = size_of(bcx, contents_ty);
57 let ccx = bcx_ccx(bcx);
58 check non_ty_var(ccx, contents_ty);
59 let llptrty = T_ptr(type_of_inner(ccx, bcx.sp, contents_ty));
61 r = trans_shared_malloc(bcx, llptrty, llsz);
68 fn make_free_glue(cx: @block_ctxt, v: ValueRef, t: ty::t)
69 : type_is_unique_box(cx, t) -> @block_ctxt {
72 let free_cx = new_sub_block_ctxt(bcx, "uniq_free");
73 let next_cx = new_sub_block_ctxt(bcx, "uniq_free_next");
74 let vptr = Load(bcx, v);
75 let null_test = IsNull(bcx, vptr);
76 CondBr(bcx, null_test, next_cx.llbb, free_cx.llbb);
79 let bcx = drop_ty(bcx, vptr, content_ty(cx, t));
80 let bcx = trans_shared_free(bcx, vptr);
81 Store(bcx, C_null(val_ty(vptr)), v);
82 Br(bcx, next_cx.llbb);
87 fn content_ty(bcx: @block_ctxt, t: ty::t)
88 : type_is_unique_box(bcx, t) -> ty::t {
90 alt ty::struct(bcx_tcx(bcx), t) {
91 ty::ty_uniq({ty: ct, _}) { ct }
95 fn copy_val(cx: @block_ctxt, dst: ValueRef, src: ValueRef,
96 ty: ty::t) : type_is_unique_box(cx, ty) -> @block_ctxt {
98 let content_ty = content_ty(cx, ty);
99 let {bcx, val: llptr} = alloc_uniq(cx, ty);
100 Store(bcx, llptr, dst);
102 let src = Load(bcx, src);
104 let bcx = trans::copy_val(bcx, INIT, dst, src, content_ty);
108 fn autoderef(bcx: @block_ctxt, v: ValueRef, t: ty::t)
109 : type_is_unique_box(bcx, t) -> {v: ValueRef, t: ty::t} {
111 let content_ty = content_ty(bcx, t);
112 ret {v: v, t: content_ty};
115 fn duplicate(bcx: @block_ctxt, v: ValueRef, t: ty::t)
116 : type_is_unique_box(bcx, t) -> @block_ctxt {
118 let content_ty = content_ty(bcx, t);
119 let {bcx, val: llptr} = alloc_uniq(bcx, t);
121 let src = Load(bcx, v);
122 let src = load_if_immediate(bcx, src, content_ty);
124 let bcx = trans::copy_val(bcx, INIT, dst, src, content_ty);