diff options
| author | Marijn Haverbeke <marijnh@gmail.com> | 2011-08-22 11:41:49 +0200 |
|---|---|---|
| committer | Marijn Haverbeke <marijnh@gmail.com> | 2011-08-22 11:41:49 +0200 |
| commit | cd5e4c21ee1355603bea8c6b478678a51b45b277 (patch) | |
| tree | 4b6979788e97650f998a06fc34579cf8c64c7626 /src/comp | |
| parent | 7588a895538800ffe88e2a4273a47020fec42e7d (diff) | |
Add skeleton of copy glue that actually copies
Diffstat (limited to 'src/comp')
| -rw-r--r-- | src/comp/back/abi.rs | 7 | ||||
| -rw-r--r-- | src/comp/middle/trans.rs | 64 | ||||
| -rw-r--r-- | src/comp/middle/trans_common.rs | 24 |
3 files changed, 79 insertions, 16 deletions
diff --git a/src/comp/back/abi.rs b/src/comp/back/abi.rs index 3ee9a546718..2e2bddba592 100644 --- a/src/comp/back/abi.rs +++ b/src/comp/back/abi.rs @@ -52,10 +52,9 @@ const tydesc_field_align: int = 2; const tydesc_field_take_glue: int = 3; const tydesc_field_drop_glue: int = 4; const tydesc_field_free_glue: int = 5; -const tydesc_field_sever_glue: int = 6; -const tydesc_field_mark_glue: int = 7; -// FIXME no longer used in rustc, drop when rustboot is gone -const tydesc_field_obj_drop_glue: int = 8; +const tydesc_field_copy_glue: int = 6; +const tydesc_field_sever_glue: int = 7; +const tydesc_field_mark_glue: int = 8; const tydesc_field_is_stateful: int = 9; const tydesc_field_cmp_glue: int = 10; const tydesc_field_shape: int = 11; diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs index 2271fe43ede..4825730d7e8 100644 --- a/src/comp/middle/trans.rs +++ b/src/comp/middle/trans.rs @@ -1120,12 +1120,16 @@ fn declare_tydesc(cx: &@local_ctxt, sp: &span, t: &ty::t, ty_params: &[uint]) mutable drop_glue: none::<ValueRef>, mutable free_glue: none::<ValueRef>, mutable cmp_glue: none::<ValueRef>, + mutable copy_glue: none::<ValueRef>, ty_params: ty_params}; log "--- declare_tydesc " + ty_to_str(cx.ccx.tcx, t); ret info; } -type make_generic_glue_helper_fn = fn(&@block_ctxt, ValueRef, &ty::t); +tag glue_helper { + default_helper(fn(&@block_ctxt, ValueRef, &ty::t)); + copy_helper(fn(&@block_ctxt, ValueRef, ValueRef, &ty::t)); +} fn declare_generic_glue(cx: &@local_ctxt, t: &ty::t, llfnty: TypeRef, name: &str) -> ValueRef { @@ -1141,7 +1145,7 @@ fn declare_generic_glue(cx: &@local_ctxt, t: &ty::t, llfnty: TypeRef, fn make_generic_glue_inner(cx: &@local_ctxt, sp: &span, t: &ty::t, llfn: ValueRef, - helper: &make_generic_glue_helper_fn, + helper: &glue_helper, ty_params: &[uint]) -> ValueRef { let fcx = new_fn_ctxt(cx, sp, llfn); llvm::LLVMSetLinkage(llfn, @@ -1177,13 +1181,22 @@ fn make_generic_glue_inner(cx: &@local_ctxt, sp: &span, t: &ty::t, let lltop = bcx.llbb; let llrawptr0 = llvm::LLVMGetParam(llfn, 4u); let llval0 = bcx.build.BitCast(llrawptr0, llty); - helper(bcx, llval0, t); + alt helper { + default_helper(helper) { + helper(bcx, llval0, t); + } + copy_helper(helper) { + let llrawptr1 = llvm::LLVMGetParam(llfn, 4u); + let llval1 = bcx.build.BitCast(llrawptr1, llty); + helper(bcx, llval0, llval1, t); + } + } finish_fn(fcx, lltop); ret llfn; } fn make_generic_glue(cx: &@local_ctxt, sp: &span, t: &ty::t, llfn: ValueRef, - helper: &make_generic_glue_helper_fn, ty_params: &[uint], + helper: &glue_helper, ty_params: &[uint], name: &str) -> ValueRef { if !cx.ccx.sess.get_opts().stats { ret make_generic_glue_inner(cx, sp, t, llfn, helper, ty_params); @@ -1201,6 +1214,7 @@ fn emit_tydescs(ccx: &@crate_ctxt) { for each pair: @{key: ty::t, val: @tydesc_info} in ccx.tydescs.items() { let glue_fn_ty = T_ptr(T_glue_fn(*ccx)); let cmp_fn_ty = T_ptr(T_cmp_glue_fn(*ccx)); + let copy_fn_ty = T_ptr(T_copy_glue_fn(*ccx)); let ti = pair.val; let take_glue = alt { ti.take_glue } { @@ -1222,6 +1236,11 @@ fn emit_tydescs(ccx: &@crate_ctxt) { none. { ccx.stats.n_null_glues += 1u; C_null(cmp_fn_ty) } some(v) { ccx.stats.n_real_glues += 1u; v } }; + let copy_glue = + alt { ti.copy_glue } { + none. { ccx.stats.n_null_glues += 1u; C_null(copy_fn_ty) } + some(v) { ccx.stats.n_real_glues += 1u; v } + }; let shape = shape::shape_of(ccx, pair.key); let shape_tables = @@ -1236,9 +1255,9 @@ fn emit_tydescs(ccx: &@crate_ctxt) { take_glue, // take_glue drop_glue, // drop_glue free_glue, // free_glue + copy_glue, // copy_glue C_null(glue_fn_ty), // sever_glue C_null(glue_fn_ty), // mark_glue - C_null(glue_fn_ty), // obj_drop_glue C_null(glue_fn_ty), // is_stateful cmp_glue, // cmp_glue C_shape(ccx, shape), // shape @@ -1253,6 +1272,11 @@ fn emit_tydescs(ccx: &@crate_ctxt) { } } +fn make_copy_glue(cx: &@block_ctxt, dst: ValueRef, src: ValueRef, t: &ty::t) { + let bcx = memmove_ty(cx, dst, src, t).bcx; + build_return(bcx); +} + fn make_take_glue(cx: &@block_ctxt, v: ValueRef, t: &ty::t) { // NB: v is an *alias* of type t here, not a direct value. @@ -1970,6 +1994,7 @@ fn lazily_emit_all_tydesc_glue(cx: &@block_ctxt, lazily_emit_tydesc_glue(cx, abi::tydesc_field_drop_glue, static_ti); lazily_emit_tydesc_glue(cx, abi::tydesc_field_free_glue, static_ti); lazily_emit_tydesc_glue(cx, abi::tydesc_field_cmp_glue, static_ti); + lazily_emit_tydesc_glue(cx, abi::tydesc_field_copy_glue, static_ti); } fn lazily_emit_all_generic_info_tydesc_glues(cx: &@block_ctxt, @@ -1995,7 +2020,8 @@ fn lazily_emit_tydesc_glue(cx: &@block_ctxt, field: int, declare_generic_glue(lcx, ti.ty, T_glue_fn(*lcx.ccx), "take"); ti.take_glue = some::<ValueRef>(glue_fn); - make_generic_glue(lcx, cx.sp, ti.ty, glue_fn, make_take_glue, + make_generic_glue(lcx, cx.sp, ti.ty, glue_fn, + default_helper(make_take_glue), ti.ty_params, "take"); log #fmt["--- lazily_emit_tydesc_glue TAKE %s", ty_to_str(bcx_tcx(cx), ti.ty)]; @@ -2012,13 +2038,14 @@ fn lazily_emit_tydesc_glue(cx: &@block_ctxt, field: int, declare_generic_glue(lcx, ti.ty, T_glue_fn(*lcx.ccx), "drop"); ti.drop_glue = some::<ValueRef>(glue_fn); - make_generic_glue(lcx, cx.sp, ti.ty, glue_fn, make_drop_glue, + make_generic_glue(lcx, cx.sp, ti.ty, glue_fn, + default_helper(make_drop_glue), ti.ty_params, "drop"); log #fmt["--- lazily_emit_tydesc_glue DROP %s", ty_to_str(bcx_tcx(cx), ti.ty)]; } } - } else if field == abi::tydesc_field_free_glue { + } else if field == abi::tydesc_field_free_glue { alt { ti.free_glue } { some(_) { } none. { @@ -2029,7 +2056,8 @@ fn lazily_emit_tydesc_glue(cx: &@block_ctxt, field: int, declare_generic_glue(lcx, ti.ty, T_glue_fn(*lcx.ccx), "free"); ti.free_glue = some::<ValueRef>(glue_fn); - make_generic_glue(lcx, cx.sp, ti.ty, glue_fn, make_free_glue, + make_generic_glue(lcx, cx.sp, ti.ty, glue_fn, + default_helper(make_free_glue), ti.ty_params, "free"); log #fmt["--- lazily_emit_tydesc_glue FREE %s", ty_to_str(bcx_tcx(cx), ti.ty)]; @@ -2046,6 +2074,21 @@ fn lazily_emit_tydesc_glue(cx: &@block_ctxt, field: int, ty_to_str(bcx_tcx(cx), ti.ty)]; } } + } else if field == abi::tydesc_field_copy_glue { + alt { ti.copy_glue } { + some(_) {} + none. { + let lcx = cx.fcx.lcx; + let glue_fn = + declare_generic_glue(lcx, ti.ty, T_copy_glue_fn(*lcx.ccx), + "copy"); + ti.copy_glue = some(glue_fn); + make_generic_glue(lcx, cx.sp, ti.ty, glue_fn, + copy_helper(make_copy_glue), + ti.ty_params, "copy"); + + } + } } } } @@ -2065,8 +2108,6 @@ fn call_tydesc_glue_full(cx: &@block_ctxt, v: ValueRef, tydesc: ValueRef, static_glue_fn = sti.drop_glue; } else if field == abi::tydesc_field_free_glue { static_glue_fn = sti.free_glue; - } else if field == abi::tydesc_field_cmp_glue { - static_glue_fn = sti.cmp_glue; } } } @@ -2787,6 +2828,7 @@ mod ivec { lazily_emit_tydesc_glue(bcx, abi::tydesc_field_take_glue, none); lazily_emit_tydesc_glue(bcx, abi::tydesc_field_drop_glue, none); lazily_emit_tydesc_glue(bcx, abi::tydesc_field_free_glue, none); + lazily_emit_tydesc_glue(bcx, abi::tydesc_field_copy_glue, none); let rhs_len_and_data = get_len_and_data(bcx, rhs, unit_ty); let rhs_len = rhs_len_and_data.len; let rhs_data = rhs_len_and_data.data; diff --git a/src/comp/middle/trans_common.rs b/src/comp/middle/trans_common.rs index 286410e8063..3f6e7478333 100644 --- a/src/comp/middle/trans_common.rs +++ b/src/comp/middle/trans_common.rs @@ -85,6 +85,7 @@ type tydesc_info = mutable drop_glue: option::t<ValueRef>, mutable free_glue: option::t<ValueRef>, mutable cmp_glue: option::t<ValueRef>, + mutable copy_glue: option::t<ValueRef>, ty_params: [uint]}; /* @@ -605,6 +606,14 @@ fn T_cmp_glue_fn(cx: &crate_ctxt) -> TypeRef { ret t; } +fn T_copy_glue_fn(cx: &crate_ctxt) -> TypeRef { + let s = "copy_glue_fn"; + if cx.tn.name_has_type(s) { ret cx.tn.get_type(s); } + let t = T_tydesc_field(cx, abi::tydesc_field_copy_glue); + cx.tn.associate(s, t); + ret t; +} + fn T_tydesc(taskptr_type: TypeRef) -> TypeRef { let tydesc = T_named_struct("tydesc"); let tydescpp = T_ptr(T_ptr(tydesc)); @@ -615,10 +624,13 @@ fn T_tydesc(taskptr_type: TypeRef) -> TypeRef { let cmp_glue_fn_ty = T_ptr(T_fn([T_ptr(T_i1()), taskptr_type, T_ptr(tydesc), tydescpp, pvoid, pvoid, T_i8()], T_void())); + let copy_glue_fn_ty = + T_ptr(T_fn([T_ptr(T_nil()), taskptr_type, T_ptr(T_nil()), tydescpp, + pvoid, pvoid], T_void())); let elems = [tydescpp, T_int(), T_int(), glue_fn_ty, glue_fn_ty, glue_fn_ty, - glue_fn_ty, glue_fn_ty, glue_fn_ty, glue_fn_ty, cmp_glue_fn_ty, + copy_glue_fn_ty, glue_fn_ty, glue_fn_ty, glue_fn_ty, cmp_glue_fn_ty, T_ptr(T_i8()), T_ptr(T_i8()), T_int()]; set_struct_body(tydesc, elems); ret tydesc; @@ -892,3 +904,13 @@ fn C_shape(ccx: &@crate_ctxt, bytes: &[u8]) -> ValueRef { ret llvm::LLVMConstPointerCast(llglobal, T_ptr(T_i8())); } +// +// Local Variables: +// mode: rust +// fill-column: 78; +// indent-tabs-mode: nil +// c-basic-offset: 4 +// buffer-file-coding-system: utf-8-unix +// compile-command: "make -k -C $RBUILD 2>&1 | sed -e 's/\\/x\\//x:\\//g'"; +// End: +// |
