Skip to content

Commit 2ebfbbc

Browse files
committed
---
yaml --- r: 2282 b: refs/heads/master c: c39a95d h: refs/heads/master v: v3
1 parent ccfe4d2 commit 2ebfbbc

File tree

3 files changed

+62
-41
lines changed

3 files changed

+62
-41
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
---
2-
refs/heads/master: 9aeb67987c93c611be7e74b39630dd81c57acefb
2+
refs/heads/master: c39a95da90a3d8247e011f6a42f0c53ced34de97

trunk/src/comp/back/abi.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ const int tydesc_field_drop_glue = 4;
3838
const int tydesc_field_free_glue = 5;
3939
const int tydesc_field_sever_glue = 6;
4040
const int tydesc_field_mark_glue = 7;
41+
// FIXME no longer used in rustc, drop when rustboot is gone
4142
const int tydesc_field_obj_drop_glue = 8;
4243
const int tydesc_field_is_stateful = 9;
4344
const int tydesc_field_cmp_glue = 10;

trunk/src/comp/middle/trans.rs

Lines changed: 60 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -359,6 +359,11 @@ fn T_glue_fn(type_names tn) -> TypeRef {
359359
ret t;
360360
}
361361

362+
fn T_dtor(@crate_ctxt ccx, TypeRef llself_ty) -> TypeRef {
363+
ret type_of_fn_full(ccx, ast.proto_fn, some[TypeRef](llself_ty),
364+
_vec.empty[ty.arg](), ty.mk_nil(ccx.tcx), 0u);
365+
}
366+
362367
fn T_cmp_glue_fn(type_names tn) -> TypeRef {
363368
auto s = "cmp_glue_fn";
364369
if (tn.name_has_type(s)) {
@@ -763,7 +768,7 @@ fn type_of_inner(@crate_ctxt cx, ty.t t) -> TypeRef {
763768
auto th = mk_type_handle();
764769
auto self_ty = llvm.LLVMResolveTypeHandle(th.llth);
765770

766-
let vec[TypeRef] mtys = vec();
771+
let vec[TypeRef] mtys = vec(T_ptr(T_i8()));
767772
for (ty.method m in meths) {
768773
let TypeRef mty =
769774
type_of_fn_full(cx, m.proto,
@@ -1618,7 +1623,8 @@ fn get_tydesc(&@block_ctxt cx, ty.t t) -> result {
16181623

16191624
// Otherwise, generate a tydesc if necessary, and return it.
16201625
let vec[uint] tps = vec();
1621-
ret res(cx, get_static_tydesc(cx, t, tps).tydesc);
1626+
auto st = get_static_tydesc(cx, t, tps).tydesc;
1627+
ret res(cx, st);
16221628
}
16231629

16241630
fn get_static_tydesc(&@block_ctxt cx,
@@ -1901,25 +1907,26 @@ fn make_drop_glue(@block_ctxt cx, ValueRef v0, ty.t t) {
19011907
}
19021908

19031909
case (ty.ty_obj(_)) {
1904-
fn hit_zero(@block_ctxt cx, ValueRef v) -> result {
1905-
1906-
// Call through the obj's own fields-drop glue first.
1910+
fn hit_zero(@block_ctxt cx, ValueRef b, ValueRef o) -> result {
19071911
auto body =
1908-
cx.build.GEP(v,
1912+
cx.build.GEP(b,
19091913
vec(C_int(0),
19101914
C_int(abi.box_rc_field_body)));
1911-
19121915
auto tydescptr =
19131916
cx.build.GEP(body,
19141917
vec(C_int(0),
19151918
C_int(abi.obj_body_elt_tydesc)));
1919+
auto tydesc = cx.build.Load(tydescptr);
19161920

1917-
call_tydesc_glue_full(cx, body, cx.build.Load(tydescptr),
1921+
auto cx_ = maybe_call_dtor(cx, o);
1922+
1923+
// Call through the obj's own fields-drop glue first.
1924+
call_tydesc_glue_full(cx_, body, tydesc,
19181925
abi.tydesc_field_drop_glue);
19191926

19201927
// Then free the body.
19211928
// FIXME: switch gc/non-gc on layer of the type.
1922-
ret trans_non_gc_free(cx, v);
1929+
ret trans_non_gc_free(cx_, b);
19231930
}
19241931
auto box_cell =
19251932
cx.build.GEP(v0,
@@ -1929,7 +1936,7 @@ fn make_drop_glue(@block_ctxt cx, ValueRef v0, ty.t t) {
19291936
auto boxptr = cx.build.Load(box_cell);
19301937

19311938
rslt = decr_refcnt_and_if_zero(cx, boxptr,
1932-
bind hit_zero(_, boxptr),
1939+
bind hit_zero(_, boxptr, v0),
19331940
"free obj",
19341941
T_int(), C_int(0));
19351942
}
@@ -2704,6 +2711,27 @@ fn call_tydesc_glue(@block_ctxt cx, ValueRef v,
27042711
ret res(td.bcx, C_nil());
27052712
}
27062713

2714+
fn maybe_call_dtor(@block_ctxt cx, ValueRef v) -> @block_ctxt {
2715+
auto vtbl = cx.build.GEP(v, vec(C_int(0), C_int(abi.obj_field_vtbl)));
2716+
vtbl = cx.build.Load(vtbl);
2717+
auto dtor_ptr = cx.build.GEP(vtbl, vec(C_int(0), C_int(0)));
2718+
dtor_ptr = cx.build.Load(dtor_ptr);
2719+
dtor_ptr = cx.build.BitCast(dtor_ptr,
2720+
T_ptr(T_dtor(cx.fcx.lcx.ccx, val_ty(v))));
2721+
2722+
auto dtor_cx = new_sub_block_ctxt(cx, "dtor");
2723+
auto after_cx = new_sub_block_ctxt(cx, "after_dtor");
2724+
auto test = cx.build.ICmp(lib.llvm.LLVMIntNE, dtor_ptr,
2725+
C_null(val_ty(dtor_ptr)));
2726+
cx.build.CondBr(test, dtor_cx.llbb, after_cx.llbb);
2727+
2728+
// FIXME need to pass type params (?)
2729+
dtor_cx.build.FastCall(dtor_ptr, vec(C_null(T_ptr(T_nil())),
2730+
cx.fcx.lltaskptr, v));
2731+
dtor_cx.build.Br(after_cx.llbb);
2732+
ret after_cx;
2733+
}
2734+
27072735
fn call_cmp_glue(@block_ctxt cx, ValueRef lhs, ValueRef rhs, ty.t t,
27082736
ValueRef llop) -> result {
27092737
// We can't use call_tydesc_glue_full() and friends here because compare
@@ -4110,12 +4138,13 @@ fn trans_field(@block_ctxt cx, &ast.span sp, ValueRef v, ty.t t0,
41104138
vec(C_int(0),
41114139
C_int(abi.obj_field_vtbl)));
41124140
vtbl = r.bcx.build.Load(vtbl);
4141+
// +1 because slot #0 contains the destructor
41134142
auto v = r.bcx.build.GEP(vtbl, vec(C_int(0),
4114-
C_int(ix as int)));
4143+
C_int((ix + 1u) as int)));
41154144

41164145
auto lvo = lval_mem(r.bcx, v);
41174146
let ty.t fn_ty = ty.method_ty_to_fn_ty(cx.fcx.lcx.ccx.tcx,
4118-
methods.(ix));
4147+
methods.(ix));
41194148
ret rec(llobj = some[ValueRef](r.val),
41204149
method_ty = some[ty.t](fn_ty)
41214150
with lvo);
@@ -6102,7 +6131,6 @@ fn populate_fn_ctxt_from_llself(@fn_ctxt fcx, self_vt llself) {
61026131
fn trans_fn(@local_ctxt cx, &ast._fn f, ast.def_id fid,
61036132
option.t[tup(TypeRef, ty.t)] ty_self,
61046133
&vec[ast.ty_param] ty_params, &ast.ann ann) {
6105-
61066134
auto llfndecl = cx.ccx.item_ids.get(fid);
61076135

61086136
auto fcx = new_fn_ctxt(cx, llfndecl);
@@ -6145,7 +6173,15 @@ fn trans_vtbl(@local_ctxt cx,
61456173
ty.t self_ty,
61466174
&ast._obj ob,
61476175
&vec[ast.ty_param] ty_params) -> ValueRef {
6148-
let vec[ValueRef] methods = vec();
6176+
auto dtor = C_null(T_ptr(T_i8()));
6177+
alt (ob.dtor) {
6178+
case (some[@ast.method](?d)) {
6179+
auto dtor_1 = trans_dtor(cx, llself_ty, self_ty, ty_params, d);
6180+
dtor = llvm.LLVMConstBitCast(dtor_1, val_ty(dtor));
6181+
}
6182+
case (none[@ast.method]) {}
6183+
}
6184+
let vec[ValueRef] methods = vec(dtor);
61496185

61506186
fn meth_lteq(&@ast.method a, &@ast.method b) -> bool {
61516187
ret _str.lteq(a.node.ident, b.node.ident);
@@ -6195,16 +6231,7 @@ fn trans_dtor(@local_ctxt cx,
61956231
&vec[ast.ty_param] ty_params,
61966232
&@ast.method dtor) -> ValueRef {
61976233

6198-
auto llfnty = T_nil();
6199-
alt (ty.struct(cx.ccx.tcx, node_ann_type(cx.ccx, dtor.node.ann))) {
6200-
case (ty.ty_fn(?proto, ?inputs, ?output)) {
6201-
llfnty = type_of_fn_full(cx.ccx, proto,
6202-
some[TypeRef](llself_ty),
6203-
inputs, output,
6204-
_vec.len[ast.ty_param](ty_params));
6205-
}
6206-
}
6207-
6234+
auto llfnty = T_dtor(cx.ccx, llself_ty);
62086235
let @local_ctxt dcx = extend_path(cx, "drop");
62096236
let str s = mangle_name_by_seq(dcx.ccx, dcx.path, "drop");
62106237
let ValueRef llfn = decl_internal_fastcall_fn(cx.ccx.llmod, s, llfnty);
@@ -6235,18 +6262,19 @@ fn trans_obj(@local_ctxt cx, &ast._obj ob, ast.def_id oid,
62356262
auto fcx = new_fn_ctxt(cx, llctor_decl);
62366263
create_llargs_for_fn_args(fcx, ast.proto_fn,
62376264
none[tup(TypeRef, ty.t)],
6238-
ret_ty_of_fn(cx.ccx, ann),
6265+
ret_ty_of_fn(ccx, ann),
62396266
fn_args, ty_params);
62406267

6241-
let vec[ty.arg] arg_tys = arg_tys_of_fn(cx.ccx, ann);
6268+
let vec[ty.arg] arg_tys = arg_tys_of_fn(ccx, ann);
62426269
copy_args_to_allocas(fcx, fn_args, arg_tys);
62436270

62446271
auto bcx = new_top_block_ctxt(fcx);
62456272
auto lltop = bcx.llbb;
62466273

6247-
auto self_ty = ret_ty_of_fn(cx.ccx, ann);
6274+
auto self_ty = ret_ty_of_fn(ccx, ann);
62486275
auto llself_ty = type_of(ccx, self_ty);
62496276
auto pair = bcx.fcx.llretptr;
6277+
62506278
auto vtbl = trans_vtbl(cx, llself_ty, self_ty, ob, ty_params);
62516279
auto pair_vtbl = bcx.build.GEP(pair,
62526280
vec(C_int(0),
@@ -6270,19 +6298,19 @@ fn trans_obj(@local_ctxt cx, &ast._obj ob, ast.def_id oid,
62706298
}
62716299

62726300
// Synthesize an obj body type.
6273-
auto tydesc_ty = ty.mk_type(cx.ccx.tcx);
6301+
auto tydesc_ty = ty.mk_type(ccx.tcx);
62746302
let vec[ty.t] tps = vec();
62756303
for (ast.ty_param tp in ty_params) {
62766304
_vec.push[ty.t](tps, tydesc_ty);
62776305
}
62786306

6279-
let ty.t typarams_ty = ty.mk_imm_tup(cx.ccx.tcx, tps);
6280-
let ty.t fields_ty = ty.mk_imm_tup(cx.ccx.tcx, obj_fields);
6281-
let ty.t body_ty = ty.mk_imm_tup(cx.ccx.tcx,
6307+
let ty.t typarams_ty = ty.mk_imm_tup(ccx.tcx, tps);
6308+
let ty.t fields_ty = ty.mk_imm_tup(ccx.tcx, obj_fields);
6309+
let ty.t body_ty = ty.mk_imm_tup(ccx.tcx,
62826310
vec(tydesc_ty,
62836311
typarams_ty,
62846312
fields_ty));
6285-
let ty.t boxed_body_ty = ty.mk_imm_box(cx.ccx.tcx, body_ty);
6313+
let ty.t boxed_body_ty = ty.mk_imm_box(ccx.tcx, body_ty);
62866314

62876315
// Malloc a box for the body.
62886316
auto box = trans_malloc_boxed(bcx, body_ty);
@@ -6301,14 +6329,6 @@ fn trans_obj(@local_ctxt cx, &ast._obj ob, ast.def_id oid,
63016329
vec(0, abi.obj_body_elt_tydesc));
63026330
bcx = body_tydesc.bcx;
63036331

6304-
auto dtor = C_null(T_ptr(T_glue_fn(ccx.tn)));
6305-
alt (ob.dtor) {
6306-
case (some[@ast.method](?d)) {
6307-
dtor = trans_dtor(cx, llself_ty, self_ty, ty_params, d);
6308-
}
6309-
case (none[@ast.method]) {}
6310-
}
6311-
63126332
auto body_td = get_tydesc(bcx, body_ty);
63136333
bcx = body_td.bcx;
63146334
bcx.build.Store(body_td.val, body_tydesc.val);

0 commit comments

Comments
 (0)