Add skeleton of copy glue that actually copies
This commit is contained in:
parent
7588a89553
commit
cd5e4c21ee
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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:
|
||||
//
|
||||
|
@ -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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user