From c930af74d5ad02cee4a540b0d0a91b12b3d6e58c Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Mon, 22 Aug 2011 12:03:11 +0200 Subject: [PATCH] Write call_copy_glue --- src/comp/middle/trans.rs | 41 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 40 insertions(+), 1 deletion(-) diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs index 4825730d7e8..0b62c685638 100644 --- a/src/comp/middle/trans.rs +++ b/src/comp/middle/trans.rs @@ -1186,7 +1186,7 @@ fn make_generic_glue_inner(cx: &@local_ctxt, sp: &span, t: &ty::t, helper(bcx, llval0, t); } copy_helper(helper) { - let llrawptr1 = llvm::LLVMGetParam(llfn, 4u); + let llrawptr1 = llvm::LLVMGetParam(llfn, 5u); let llval1 = bcx.build.BitCast(llrawptr1, llty); helper(bcx, llval0, llval1, t); } @@ -2178,6 +2178,45 @@ fn call_cmp_glue(cx: &@block_ctxt, lhs: ValueRef, rhs: ValueRef, t: &ty::t, ret rslt(r.bcx, r.bcx.build.Load(llcmpresultptr)); } +fn call_copy_glue(cx: &@block_ctxt, dst: ValueRef, src: ValueRef, t: &ty::t, + take: bool) -> @block_ctxt { + // You can't call this on immediate types. Those are simply copied with + // Load/Store. + assert !type_is_immediate(bcx_ccx(cx), t); + let srcptr = cx.build.BitCast(src, T_ptr(T_i8())); + let dstptr = cx.build.BitCast(dst, T_ptr(T_i8())); + let ti = none; + let {bcx, val: lltydesc} = get_tydesc(cx, t, false, ti).result; + lazily_emit_tydesc_glue(cx, abi::tydesc_field_copy_glue, ti); + let lltydescs = bcx.build.GEP + (lltydesc, [C_int(0), C_int(abi::tydesc_field_first_param)]); + lltydescs = bcx.build.Load(lltydescs); + + let llfn = alt ti { + none. { + bcx.build.Load(bcx.build.GEP + (lltydesc, [C_int(0), C_int(abi::tydesc_field_copy_glue)])) + } + some(sti) { option::get(sti.copy_glue) } + }; + bcx.build.Call(llfn, [C_null(T_ptr(T_nil())), bcx.fcx.lltaskptr, + C_null(T_ptr(T_nil())), lltydescs, srcptr, dstptr]); + if take { + lazily_emit_tydesc_glue(cx, abi::tydesc_field_take_glue, ti); + llfn = alt ti { + none. { + bcx.build.Load(bcx.build.GEP + (lltydesc, [C_int(0), C_int(abi::tydesc_field_take_glue)])) + } + some(sti) { option::get(sti.take_glue) } + }; + bcx.build.Call(llfn, [C_null(T_ptr(T_nil())), bcx.fcx.lltaskptr, + C_null(T_ptr(T_nil())), lltydescs, dstptr]); + } + ret bcx; +} + + // Compares two values. Performs the simple scalar comparison if the types are // scalar and calls to comparison glue otherwise. fn compare(cx: &@block_ctxt, lhs: ValueRef, rhs: ValueRef, t: &ty::t, -- GitLab