Add skeleton of copy glue that actually copies

This commit is contained in:
Marijn Haverbeke 2011-08-22 11:41:49 +02:00
parent 7588a89553
commit cd5e4c21ee
4 changed files with 82 additions and 17 deletions

View File

@ -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;

View File

@ -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;

View File

@ -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:
//

View File

@ -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;