From cd5e4c21ee1355603bea8c6b478678a51b45b277 Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Mon, 22 Aug 2011 11:41:49 +0200 Subject: [PATCH] Add skeleton of copy glue that actually copies --- src/comp/back/abi.rs | 7 ++-- src/comp/middle/trans.rs | 64 +++++++++++++++++++++++++++------ src/comp/middle/trans_common.rs | 24 ++++++++++++- src/rt/rust_internal.h | 4 ++- 4 files changed, 82 insertions(+), 17 deletions(-) diff --git a/src/comp/back/abi.rs b/src/comp/back/abi.rs index 3ee9a5467182..2e2bddba592c 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 2271fe43ede2..4825730d7e8f 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::, mutable free_glue: none::, mutable cmp_glue: none::, + mutable copy_glue: none::, 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::(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::(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::(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 286410e8063b..3f6e74783333 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, mutable free_glue: option::t, mutable cmp_glue: option::t, + mutable copy_glue: option::t, 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: +// diff --git a/src/rt/rust_internal.h b/src/rt/rust_internal.h index a590c7e22ad9..dd9f1d0cbc89 100644 --- a/src/rt/rust_internal.h +++ b/src/rt/rust_internal.h @@ -257,6 +257,8 @@ struct rust_timer { typedef void CDECL (glue_fn)(void *, rust_task *, void *, const type_desc **, void *); +typedef void CDECL (copy_glue_fn)(void *, rust_task *, void *, + const type_desc **, void *, void *); typedef void CDECL (cmp_glue_fn)(void *, rust_task *, void *, const type_desc **, void *, void *, int8_t); @@ -275,9 +277,9 @@ struct type_desc { glue_fn *take_glue; glue_fn *drop_glue; glue_fn *free_glue; + copy_glue_fn *copy_glue; glue_fn *sever_glue; // For GC. glue_fn *mark_glue; // For GC. - glue_fn *obj_drop_glue; // For custom destructors. uintptr_t is_stateful; cmp_glue_fn *cmp_glue; const uint8_t *shape;