2011-09-22 11:44:18 -07:00
|
|
|
import syntax::ast;
|
|
|
|
import lib::llvm::llvm::ValueRef;
|
|
|
|
import trans_common::*;
|
|
|
|
import trans_build::*;
|
|
|
|
import trans::{
|
|
|
|
trans_shared_malloc,
|
2011-09-24 01:52:45 -07:00
|
|
|
type_of_inner,
|
2011-09-22 11:44:18 -07:00
|
|
|
size_of,
|
|
|
|
node_id_type,
|
|
|
|
INIT,
|
|
|
|
trans_shared_free,
|
|
|
|
drop_ty,
|
2011-09-23 23:00:46 -07:00
|
|
|
new_sub_block_ctxt,
|
2011-09-27 13:19:55 +02:00
|
|
|
load_if_immediate,
|
|
|
|
dest
|
2011-09-22 11:44:18 -07:00
|
|
|
};
|
|
|
|
|
2011-12-13 16:50:11 -08:00
|
|
|
export trans_uniq, make_free_glue, type_is_unique_box, autoderef, duplicate,
|
|
|
|
alloc_uniq;
|
2011-09-22 12:22:23 -07:00
|
|
|
|
|
|
|
pure fn type_is_unique_box(bcx: @block_ctxt, ty: ty::t) -> bool {
|
2011-09-24 15:36:09 -07:00
|
|
|
ty::type_is_unique_box(bcx_tcx(bcx), ty)
|
2011-09-22 12:22:23 -07:00
|
|
|
}
|
2011-09-22 11:44:18 -07:00
|
|
|
|
2011-09-27 13:19:55 +02:00
|
|
|
fn trans_uniq(bcx: @block_ctxt, contents: @ast::expr,
|
|
|
|
node_id: ast::node_id, dest: dest) -> @block_ctxt {
|
|
|
|
let uniq_ty = node_id_type(bcx_ccx(bcx), node_id);
|
2011-09-22 12:22:23 -07:00
|
|
|
check type_is_unique_box(bcx, uniq_ty);
|
2011-09-22 11:44:18 -07:00
|
|
|
let {bcx, val: llptr} = alloc_uniq(bcx, uniq_ty);
|
2011-09-27 13:19:55 +02:00
|
|
|
add_clean_free(bcx, llptr, true);
|
2011-10-05 10:21:48 +02:00
|
|
|
bcx = trans::trans_expr_save_in(bcx, contents, llptr);
|
2011-09-27 13:19:55 +02:00
|
|
|
revoke_clean(bcx, llptr);
|
|
|
|
ret trans::store_in_dest(bcx, llptr, dest);
|
2011-09-22 11:44:18 -07:00
|
|
|
}
|
|
|
|
|
2011-09-22 12:22:23 -07:00
|
|
|
fn alloc_uniq(cx: @block_ctxt, uniq_ty: ty::t)
|
|
|
|
: type_is_unique_box(cx, uniq_ty) -> result {
|
2011-09-22 12:07:38 -07:00
|
|
|
|
2011-09-22 11:44:18 -07:00
|
|
|
let bcx = cx;
|
|
|
|
let contents_ty = content_ty(bcx, uniq_ty);
|
|
|
|
let r = size_of(bcx, contents_ty);
|
|
|
|
bcx = r.bcx;
|
|
|
|
let llsz = r.val;
|
|
|
|
|
2011-09-24 01:52:45 -07:00
|
|
|
let ccx = bcx_ccx(bcx);
|
|
|
|
check non_ty_var(ccx, contents_ty);
|
|
|
|
let llptrty = T_ptr(type_of_inner(ccx, bcx.sp, contents_ty));
|
2011-09-22 11:44:18 -07:00
|
|
|
|
|
|
|
r = trans_shared_malloc(bcx, llptrty, llsz);
|
|
|
|
bcx = r.bcx;
|
|
|
|
let llptr = r.val;
|
|
|
|
|
|
|
|
ret rslt(bcx, llptr);
|
|
|
|
}
|
|
|
|
|
2011-10-10 09:51:09 +02:00
|
|
|
fn make_free_glue(cx: @block_ctxt, vptr: ValueRef, t: ty::t)
|
2011-09-22 12:22:23 -07:00
|
|
|
: type_is_unique_box(cx, t) -> @block_ctxt {
|
2011-09-22 12:07:38 -07:00
|
|
|
|
2011-09-22 12:22:23 -07:00
|
|
|
let bcx = cx;
|
2011-09-22 11:44:18 -07:00
|
|
|
let free_cx = new_sub_block_ctxt(bcx, "uniq_free");
|
|
|
|
let next_cx = new_sub_block_ctxt(bcx, "uniq_free_next");
|
|
|
|
let null_test = IsNull(bcx, vptr);
|
|
|
|
CondBr(bcx, null_test, next_cx.llbb, free_cx.llbb);
|
|
|
|
|
|
|
|
let bcx = free_cx;
|
2011-09-22 12:22:23 -07:00
|
|
|
let bcx = drop_ty(bcx, vptr, content_ty(cx, t));
|
2011-09-22 11:44:18 -07:00
|
|
|
let bcx = trans_shared_free(bcx, vptr);
|
|
|
|
Br(bcx, next_cx.llbb);
|
|
|
|
next_cx
|
|
|
|
}
|
|
|
|
|
2011-09-22 12:22:23 -07:00
|
|
|
fn content_ty(bcx: @block_ctxt, t: ty::t)
|
|
|
|
: type_is_unique_box(bcx, t) -> ty::t {
|
2011-09-22 12:07:38 -07:00
|
|
|
|
2011-09-22 11:44:18 -07:00
|
|
|
alt ty::struct(bcx_tcx(bcx), t) {
|
|
|
|
ty::ty_uniq({ty: ct, _}) { ct }
|
|
|
|
}
|
2011-09-22 13:22:53 -07:00
|
|
|
}
|
|
|
|
|
2011-09-22 16:04:27 -07:00
|
|
|
fn autoderef(bcx: @block_ctxt, v: ValueRef, t: ty::t)
|
|
|
|
: type_is_unique_box(bcx, t) -> {v: ValueRef, t: ty::t} {
|
|
|
|
|
|
|
|
let content_ty = content_ty(bcx, t);
|
|
|
|
ret {v: v, t: content_ty};
|
2011-09-22 18:05:36 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
fn duplicate(bcx: @block_ctxt, v: ValueRef, t: ty::t)
|
2011-10-10 10:58:53 +02:00
|
|
|
: type_is_unique_box(bcx, t) -> result {
|
2011-09-22 18:05:36 -07:00
|
|
|
|
|
|
|
let content_ty = content_ty(bcx, t);
|
|
|
|
let {bcx, val: llptr} = alloc_uniq(bcx, t);
|
|
|
|
|
2011-10-10 10:58:53 +02:00
|
|
|
let src = load_if_immediate(bcx, v, content_ty);
|
2011-09-22 18:05:36 -07:00
|
|
|
let dst = llptr;
|
|
|
|
let bcx = trans::copy_val(bcx, INIT, dst, src, content_ty);
|
2011-10-10 10:58:53 +02:00
|
|
|
ret rslt(bcx, dst);
|
2011-09-22 11:44:18 -07:00
|
|
|
}
|