diff options
| author | Graydon Hoare <[email protected]> | 2010-12-02 17:43:05 -0800 |
|---|---|---|
| committer | Graydon Hoare <[email protected]> | 2010-12-02 17:43:24 -0800 |
| commit | 0f41f5a8f9492cc4d27ae5b36415a8303b59d937 (patch) | |
| tree | 88d3fd36721f50c303b2b2b32615ef60af83d397 /src | |
| parent | rustc: Change fn_names and fn_ids to item_names and item_ids in trans, since ... (diff) | |
| download | rust-0f41f5a8f9492cc4d27ae5b36415a8303b59d937.tar.xz rust-0f41f5a8f9492cc4d27ae5b36415a8303b59d937.zip | |
Improve translations of unary box operator and drop_ty on boxes.
Diffstat (limited to 'src')
| -rw-r--r-- | src/comp/middle/trans.rs | 68 |
1 files changed, 46 insertions, 22 deletions
diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs index d0f98675..255e0dc6 100644 --- a/src/comp/middle/trans.rs +++ b/src/comp/middle/trans.rs @@ -374,16 +374,16 @@ fn C_struct(vec[ValueRef] elts) -> ValueRef { } fn C_tydesc(TypeRef t) -> ValueRef { - ret C_struct(vec(C_null(T_opaque()), // first_param - llvm.LLVMSizeOf(t), // size - llvm.LLVMAlignOf(t), // align - C_null(T_opaque()), // copy_glue_off - C_null(T_opaque()), // drop_glue_off - C_null(T_opaque()), // free_glue_off - C_null(T_opaque()), // sever_glue_off - C_null(T_opaque()), // mark_glue_off - C_null(T_opaque()), // obj_drop_glue_off - C_null(T_opaque()))); // is_stateful + ret C_struct(vec(C_null(T_ptr(T_opaque())), // first_param + llvm.LLVMSizeOf(t), // size + llvm.LLVMAlignOf(t), // align + C_null(T_ptr(T_opaque())), // copy_glue_off + C_null(T_ptr(T_opaque())), // drop_glue_off + C_null(T_ptr(T_opaque())), // free_glue_off + C_null(T_ptr(T_opaque())), // sever_glue_off + C_null(T_ptr(T_opaque())), // mark_glue_off + C_null(T_ptr(T_opaque())), // obj_drop_glue_off + C_null(T_ptr(T_opaque())))); // is_stateful } fn decl_fn(ModuleRef llmod, str name, uint cc, TypeRef llty) -> ValueRef { @@ -450,6 +450,19 @@ fn trans_non_gc_free(@block_ctxt cx, ValueRef v) -> result { C_int(0))); } +fn trans_malloc(@block_ctxt cx, @typeck.ty t) -> result { + auto ptr_ty = type_of(cx.fcx.ccx, t); + auto body_ty = lib.llvm.llvm.LLVMGetElementType(ptr_ty); + // FIXME: need a table to collect tydesc globals. + auto tydesc = C_int(0); + auto sz = cx.build.IntCast(lib.llvm.llvm.LLVMSizeOf(body_ty), T_int()); + auto sub = trans_upcall(cx, "upcall_malloc", vec(sz, tydesc)); + sub.val = sub.bcx.build.IntToPtr(sub.val, ptr_ty); + sub.bcx.cleanups += clean(bind drop_ty(_, sub.val, t)); + ret sub; +} + + fn incr_refcnt(@block_ctxt cx, ValueRef box_ptr) -> result { auto rc_ptr = cx.build.GEP(box_ptr, vec(C_int(0), C_int(abi.box_rc_field_refcnt))); @@ -636,16 +649,21 @@ fn drop_ty(@block_ctxt cx, T_int(), C_int(0)); } - case (typeck.ty_box(_)) { + case (typeck.ty_box(?body_ty)) { fn hit_zero(@block_ctxt cx, ValueRef v, - @typeck.ty elt_ty) -> result { - auto res = drop_ty(cx, - cx.build.GEP(v, vec(C_int(0))), - elt_ty); + @typeck.ty body_ty) -> result { + auto body = cx.build.GEP(v, + vec(C_int(0), + C_int(abi.box_rc_field_body))); + + auto res = drop_ty(cx, body, body_ty); // FIXME: switch gc/non-gc on stratum of the type. ret trans_non_gc_free(res.bcx, v); } - ret incr_refcnt(cx, v); + ret decr_refcnt_and_if_zero(cx, v, + bind hit_zero(_, v, body_ty), + "free box", + T_int(), C_int(0)); } case (_) { @@ -778,7 +796,7 @@ impure fn trans_lit(@block_ctxt cx, &ast.lit lit) -> result { C_int(len))); sub.val = sub.bcx.build.IntToPtr(sub.val, T_ptr(T_str())); - cx.cleanups += vec(clean(bind trans_drop_str(_, sub.val))); + cx.cleanups += clean(bind trans_drop_str(_, sub.val)); ret sub; } } @@ -835,13 +853,19 @@ impure fn trans_unary(@block_ctxt cx, ast.unop op, ret sub; } case (ast.box) { - auto e_ty = node_type(cx.fcx.ccx, a); - auto box_ty = T_box(e_ty); - sub.val = cx.build.Malloc(box_ty); - auto rc = sub.bcx.build.GEP(sub.val, + auto e_ty = typeck.expr_ty(e); + auto e_val = sub.val; + sub = trans_malloc(sub.bcx, node_ann_type(sub.bcx.fcx.ccx, a)); + auto box = sub.val; + auto rc = sub.bcx.build.GEP(box, vec(C_int(0), C_int(abi.box_rc_field_refcnt))); - ret res(sub.bcx, cx.build.Store(C_int(1), rc)); + auto body = sub.bcx.build.GEP(box, + vec(C_int(0), + C_int(abi.box_rc_field_body))); + sub.bcx.build.Store(C_int(1), rc); + sub = copy_ty(sub.bcx, true, body, e_val, e_ty); + ret res(sub.bcx, box); } case (_) { cx.fcx.ccx.sess.unimpl("expr variant in trans_unary"); |