Clean up the tydesc handling code in trans.

This commit is contained in:
Michael Sullivan 2012-07-09 18:03:37 -07:00
parent ccee8cb4f9
commit 25b152397d
2 changed files with 80 additions and 119 deletions

View file

@ -367,12 +367,11 @@ fn malloc_raw_dyn(bcx: block, t: ty::t, heap: heap,
let llty = type_of(ccx, box_ptr_ty);
// Get the tydesc for the body:
let mut static_ti = none;
let lltydesc = get_tydesc(ccx, t, static_ti);
lazily_emit_all_tydesc_glue(ccx, copy static_ti);
let static_ti = get_tydesc(ccx, t);
lazily_emit_all_tydesc_glue(ccx, static_ti);
// Allocate space:
let rval = Call(bcx, upcall, ~[lltydesc, size]);
let rval = Call(bcx, upcall, ~[static_ti.tydesc, size]);
ret PointerCast(bcx, rval, llty);
}
@ -409,20 +408,10 @@ fn malloc_unique(bcx: block, t: ty::t) -> {box: ValueRef, body: ValueRef} {
// Type descriptor and type glue stuff
fn get_tydesc_simple(ccx: @crate_ctxt, t: ty::t) -> ValueRef {
let mut ti = none;
get_tydesc(ccx, t, ti)
get_tydesc(ccx, t).tydesc
}
fn get_tydesc(ccx: @crate_ctxt, t: ty::t,
&static_ti: option<@tydesc_info>) -> ValueRef {
assert !ty::type_has_params(t);
// Otherwise, generate a tydesc if necessary, and return it.
let inf = get_static_tydesc(ccx, t);
static_ti = some(inf);
inf.tydesc
}
fn get_static_tydesc(ccx: @crate_ctxt, t: ty::t) -> @tydesc_info {
fn get_tydesc(ccx: @crate_ctxt, t: ty::t) -> @tydesc_info {
alt ccx.tydescs.find(t) {
some(inf) { inf }
_ {
@ -1090,7 +1079,7 @@ fn iter_structural_ty(cx: block, av: ValueRef, t: ty::t,
}
fn lazily_emit_all_tydesc_glue(ccx: @crate_ctxt,
static_ti: option<@tydesc_info>) {
static_ti: @tydesc_info) {
lazily_emit_tydesc_glue(ccx, abi::tydesc_field_take_glue, static_ti);
lazily_emit_tydesc_glue(ccx, abi::tydesc_field_drop_glue, static_ti);
lazily_emit_tydesc_glue(ccx, abi::tydesc_field_free_glue, static_ti);
@ -1098,74 +1087,68 @@ fn lazily_emit_all_tydesc_glue(ccx: @crate_ctxt,
}
fn lazily_emit_tydesc_glue(ccx: @crate_ctxt, field: uint,
static_ti: option<@tydesc_info>) {
ti: @tydesc_info) {
let _icx = ccx.insn_ctxt("lazily_emit_tydesc_glue");
alt static_ti {
none { }
some(ti) {
if field == abi::tydesc_field_take_glue {
alt ti.take_glue {
some(_) { }
none {
#debug("+++ lazily_emit_tydesc_glue TAKE %s",
ppaux::ty_to_str(ccx.tcx, ti.ty));
let glue_fn = declare_generic_glue
(ccx, ti.ty, T_glue_fn(ccx), "take");
ti.take_glue = some(glue_fn);
make_generic_glue(ccx, ti.ty, glue_fn,
make_take_glue, "take");
#debug("--- lazily_emit_tydesc_glue TAKE %s",
ppaux::ty_to_str(ccx.tcx, ti.ty));
}
}
} else if field == abi::tydesc_field_drop_glue {
alt ti.drop_glue {
some(_) { }
none {
#debug("+++ lazily_emit_tydesc_glue DROP %s",
ppaux::ty_to_str(ccx.tcx, ti.ty));
let glue_fn =
declare_generic_glue(ccx, ti.ty, T_glue_fn(ccx), "drop");
ti.drop_glue = some(glue_fn);
make_generic_glue(ccx, ti.ty, glue_fn,
make_drop_glue, "drop");
#debug("--- lazily_emit_tydesc_glue DROP %s",
ppaux::ty_to_str(ccx.tcx, ti.ty));
}
}
} else if field == abi::tydesc_field_free_glue {
alt ti.free_glue {
some(_) { }
none {
#debug("+++ lazily_emit_tydesc_glue FREE %s",
ppaux::ty_to_str(ccx.tcx, ti.ty));
let glue_fn =
declare_generic_glue(ccx, ti.ty, T_glue_fn(ccx), "free");
ti.free_glue = some(glue_fn);
make_generic_glue(ccx, ti.ty, glue_fn,
make_free_glue, "free");
#debug("--- lazily_emit_tydesc_glue FREE %s",
ppaux::ty_to_str(ccx.tcx, ti.ty));
}
}
} else if field == abi::tydesc_field_visit_glue {
alt ti.visit_glue {
some(_) { }
none {
#debug("+++ lazily_emit_tydesc_glue VISIT %s",
ppaux::ty_to_str(ccx.tcx, ti.ty));
let glue_fn =
declare_generic_glue(ccx, ti.ty, T_glue_fn(ccx), "visit");
ti.visit_glue = some(glue_fn);
make_generic_glue(ccx, ti.ty, glue_fn,
make_visit_glue, "visit");
#debug("--- lazily_emit_tydesc_glue VISIT %s",
ppaux::ty_to_str(ccx.tcx, ti.ty));
}
}
if field == abi::tydesc_field_take_glue {
alt ti.take_glue {
some(_) { }
none {
#debug("+++ lazily_emit_tydesc_glue TAKE %s",
ppaux::ty_to_str(ccx.tcx, ti.ty));
let glue_fn = declare_generic_glue
(ccx, ti.ty, T_glue_fn(ccx), "take");
ti.take_glue = some(glue_fn);
make_generic_glue(ccx, ti.ty, glue_fn,
make_take_glue, "take");
#debug("--- lazily_emit_tydesc_glue TAKE %s",
ppaux::ty_to_str(ccx.tcx, ti.ty));
}
}
} else if field == abi::tydesc_field_drop_glue {
alt ti.drop_glue {
some(_) { }
none {
#debug("+++ lazily_emit_tydesc_glue DROP %s",
ppaux::ty_to_str(ccx.tcx, ti.ty));
let glue_fn =
declare_generic_glue(ccx, ti.ty, T_glue_fn(ccx), "drop");
ti.drop_glue = some(glue_fn);
make_generic_glue(ccx, ti.ty, glue_fn,
make_drop_glue, "drop");
#debug("--- lazily_emit_tydesc_glue DROP %s",
ppaux::ty_to_str(ccx.tcx, ti.ty));
}
}
} else if field == abi::tydesc_field_free_glue {
alt ti.free_glue {
some(_) { }
none {
#debug("+++ lazily_emit_tydesc_glue FREE %s",
ppaux::ty_to_str(ccx.tcx, ti.ty));
let glue_fn =
declare_generic_glue(ccx, ti.ty, T_glue_fn(ccx), "free");
ti.free_glue = some(glue_fn);
make_generic_glue(ccx, ti.ty, glue_fn,
make_free_glue, "free");
#debug("--- lazily_emit_tydesc_glue FREE %s",
ppaux::ty_to_str(ccx.tcx, ti.ty));
}
}
} else if field == abi::tydesc_field_visit_glue {
alt ti.visit_glue {
some(_) { }
none {
#debug("+++ lazily_emit_tydesc_glue VISIT %s",
ppaux::ty_to_str(ccx.tcx, ti.ty));
let glue_fn =
declare_generic_glue(ccx, ti.ty, T_glue_fn(ccx), "visit");
ti.visit_glue = some(glue_fn);
make_generic_glue(ccx, ti.ty, glue_fn,
make_visit_glue, "visit");
#debug("--- lazily_emit_tydesc_glue VISIT %s",
ppaux::ty_to_str(ccx.tcx, ti.ty));
}
}
}
}
}
@ -1173,13 +1156,13 @@ fn lazily_emit_tydesc_glue(ccx: @crate_ctxt, field: uint,
fn call_tydesc_glue_full(++cx: block, v: ValueRef, tydesc: ValueRef,
field: uint, static_ti: option<@tydesc_info>) {
let _icx = cx.insn_ctxt("call_tydesc_glue_full");
lazily_emit_tydesc_glue(cx.ccx(), field, static_ti);
if cx.unreachable { ret; }
if cx.unreachable { ret; }
let mut static_glue_fn = none;
alt static_ti {
none {/* no-op */ }
some(sti) {
lazily_emit_tydesc_glue(cx.ccx(), field, sti);
if field == abi::tydesc_field_take_glue {
static_glue_fn = sti.take_glue;
} else if field == abi::tydesc_field_drop_glue {
@ -1213,9 +1196,8 @@ fn call_tydesc_glue_full(++cx: block, v: ValueRef, tydesc: ValueRef,
fn call_tydesc_glue(++cx: block, v: ValueRef, t: ty::t, field: uint)
-> block {
let _icx = cx.insn_ctxt("call_tydesc_glue");
let mut ti = none;
let td = get_tydesc(cx.ccx(), t, ti);
call_tydesc_glue_full(cx, v, td, field, ti);
let ti = get_tydesc(cx.ccx(), t);
call_tydesc_glue_full(cx, v, ti.tydesc, field, some(ti));
ret cx;
}

View file

@ -146,7 +146,7 @@ fn mk_closure_tys(tcx: ty::ctxt,
fn allocate_cbox(bcx: block,
ck: ty::closure_kind,
cdata_ty: ty::t)
-> (block, ValueRef, ~[ValueRef]) {
-> ValueRef {
let _icx = bcx.insn_ctxt("closure::allocate_cbox");
let ccx = bcx.ccx(), tcx = ccx.tcx;
@ -160,42 +160,23 @@ fn allocate_cbox(bcx: block,
Store(bcx, rc, ref_cnt);
}
fn store_tydesc(bcx: block,
cdata_ty: ty::t,
llbox: ValueRef,
&ti: option<@tydesc_info>) -> block {
let bound_tydesc = GEPi(bcx, llbox, ~[0u, abi::box_field_tydesc]);
let td = base::get_tydesc(bcx.ccx(), cdata_ty, ti);
Store(bcx, td, bound_tydesc);
bcx
}
// Allocate and initialize the box:
let mut ti = none;
let mut temp_cleanups = ~[];
let (bcx, llbox) = alt ck {
let llbox = alt ck {
ty::ck_box {
get_tydesc(ccx, cdata_ty, ti);
let llbox = malloc_raw(bcx, cdata_ty, heap_shared);
(bcx, llbox)
malloc_raw(bcx, cdata_ty, heap_shared)
}
ty::ck_uniq {
let llbox = malloc_raw(bcx, cdata_ty, heap_exchange);
(bcx, llbox)
malloc_raw(bcx, cdata_ty, heap_exchange)
}
ty::ck_block {
let cbox_ty = tuplify_box_ty(tcx, cdata_ty);
let llbox = base::alloc_ty(bcx, cbox_ty);
nuke_ref_count(bcx, llbox);
(bcx, llbox)
llbox
}
};
base::lazily_emit_tydesc_glue(ccx, abi::tydesc_field_take_glue, ti);
base::lazily_emit_tydesc_glue(ccx, abi::tydesc_field_drop_glue, ti);
base::lazily_emit_tydesc_glue(ccx, abi::tydesc_field_free_glue, ti);
ret (bcx, llbox, temp_cleanups);
ret llbox;
}
type closure_result = {
@ -219,8 +200,8 @@ fn store_environment(bcx: block,
mk_closure_tys(tcx, bound_values);
// allocate closure in the heap
let mut (bcx, llbox, temp_cleanups) =
allocate_cbox(bcx, ck, cdata_ty);
let llbox = allocate_cbox(bcx, ck, cdata_ty);
let mut temp_cleanups = ~[];
// cbox_ty has the form of a tuple: (a, b, c) we want a ptr to a
// tuple. This could be a ptr in uniq or a box or on stack,
@ -567,10 +548,9 @@ fn make_opaque_cbox_take_glue(
let bcx = take_ty(bcx, tydesc_out, ty::mk_type(tcx));
// Take the data in the tuple
let ti = none;
let cdata_out = GEPi(bcx, cbox_out, ~[0u, abi::box_field_body]);
call_tydesc_glue_full(bcx, cdata_out, tydesc,
abi::tydesc_field_take_glue, ti);
abi::tydesc_field_take_glue, none);
bcx
}
}
@ -615,10 +595,9 @@ fn make_opaque_cbox_free_glue(
let tydesc = PointerCast(bcx, tydesc, lltydescty);
// Drop the tuple data then free the descriptor
let ti = none;
let cdata = GEPi(bcx, cbox, ~[0u, abi::box_field_body]);
call_tydesc_glue_full(bcx, cdata, tydesc,
abi::tydesc_field_drop_glue, ti);
abi::tydesc_field_drop_glue, none);
// Free the ty descr (if necc) and the box itself
alt ck {