From ea42911561842b4331c3fa5a5a30b97497cbf871 Mon Sep 17 00:00:00 2001 From: Graydon Hoare Date: Fri, 28 Jan 2011 14:34:25 -0800 Subject: Pass tydesc array into type glue fns as first arg. Required for derived tydescs to work. --- src/comp/middle/trans.rs | 93 +++++++++++++++++++++++++++--------------------- 1 file changed, 53 insertions(+), 40 deletions(-) (limited to 'src') diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs index 54e9426e..0303f9f2 100644 --- a/src/comp/middle/trans.rs +++ b/src/comp/middle/trans.rs @@ -237,18 +237,27 @@ fn T_task() -> TypeRef { } fn T_tydesc() -> TypeRef { + + auto th = mk_type_handle(); + auto abs_tydesc = llvm.LLVMResolveTypeHandle(th.llth); + auto pvoid = T_ptr(T_i8()); - auto glue_fn_ty = T_ptr(T_fn(vec(T_taskptr(), pvoid), T_void())); - ret T_struct(vec(pvoid, // first_param - T_int(), // size - T_int(), // align - glue_fn_ty, // take_glue_off - glue_fn_ty, // drop_glue_off - glue_fn_ty, // free_glue_off - glue_fn_ty, // sever_glue_off - glue_fn_ty, // mark_glue_off - glue_fn_ty, // obj_drop_glue_off - glue_fn_ty)); // is_stateful + auto glue_fn_ty = T_ptr(T_fn(vec(T_taskptr(), + T_ptr(abs_tydesc), + pvoid), T_void())); + auto tydesc = T_struct(vec(T_ptr(abs_tydesc), // first_param + T_int(), // size + T_int(), // align + glue_fn_ty, // take_glue_off + glue_fn_ty, // drop_glue_off + glue_fn_ty, // free_glue_off + glue_fn_ty, // sever_glue_off + glue_fn_ty, // mark_glue_off + glue_fn_ty, // obj_drop_glue_off + glue_fn_ty)); // is_stateful + + llvm.LLVMRefineType(abs_tydesc, tydesc); + ret llvm.LLVMResolveTypeHandle(th.llth); } fn T_array(TypeRef t, uint n) -> TypeRef { @@ -960,8 +969,10 @@ fn make_tydesc(@crate_ctxt cx, @ty.t t) { auto llty = type_of(cx, t); auto pvoid = T_ptr(T_i8()); - auto glue_fn_ty = T_ptr(T_fn(vec(T_taskptr(), pvoid), T_void())); - auto tydesc = C_struct(vec(C_null(pvoid), + auto glue_fn_ty = T_ptr(T_fn(vec(T_taskptr(), + T_ptr(T_tydesc()), + pvoid), T_void())); + auto tydesc = C_struct(vec(C_null(T_ptr(T_tydesc())), llsize_of(llty), llalign_of(llty), take_glue, // take_glue_off @@ -983,7 +994,9 @@ fn make_tydesc(@crate_ctxt cx, @ty.t t) { fn make_generic_glue(@crate_ctxt cx, @ty.t t, str name, val_and_ty_fn helper) -> ValueRef { - auto llfnty = T_fn(vec(T_taskptr(), T_ptr(T_i8())), T_void()); + auto llfnty = T_fn(vec(T_taskptr(), + T_ptr(T_tydesc()), + T_ptr(T_i8())), T_void()); auto fn_name = cx.names.next("_rust_" + name) + "." + ty.ty_to_str(t); fn_name = sanitize(fn_name); @@ -1001,7 +1014,7 @@ fn make_generic_glue(@crate_ctxt cx, @ty.t t, str name, llty = type_of(cx, t); } - auto llrawptr = llvm.LLVMGetParam(llfn, 1u); + auto llrawptr = llvm.LLVMGetParam(llfn, 2u); auto llval = bcx.build.BitCast(llrawptr, llty); re = helper(bcx, llval, t); @@ -1097,19 +1110,13 @@ fn make_drop_glue(@block_ctxt cx, ValueRef v, @ty.t t) -> result { cx.build.GEP(body, vec(C_int(0), C_int(abi.obj_body_elt_fields))); - auto llrawptr = cx.build.BitCast(fields, T_ptr(T_i8())); - auto tydescptr = cx.build.GEP(body, vec(C_int(0), C_int(abi.obj_body_elt_tydesc))); - auto tydesc = cx.build.Load(tydescptr); - auto llfnptr = - cx.build.GEP(tydesc, - vec(C_int(0), - C_int(abi.tydesc_field_drop_glue_off))); - auto llfn = cx.build.Load(llfnptr); - cx.build.FastCall(llfn, vec(cx.fcx.lltaskptr, llrawptr)); + + call_tydesc_glue_full(cx, fields, cx.build.Load(tydescptr), + abi.tydesc_field_drop_glue_off); // Then free the body. // FIXME: switch gc/non-gc on layer of the type. @@ -1141,19 +1148,15 @@ fn make_drop_glue(@block_ctxt cx, ValueRef v, @ty.t t) -> result { cx.build.GEP(body, vec(C_int(0), C_int(abi.closure_elt_bindings))); - auto llrawptr = cx.build.BitCast(bindings, T_ptr(T_i8())); auto tydescptr = cx.build.GEP(body, vec(C_int(0), C_int(abi.closure_elt_tydesc))); - auto tydesc = cx.build.Load(tydescptr); - auto llfnptr = - cx.build.GEP(tydesc, - vec(C_int(0), - C_int(abi.tydesc_field_drop_glue_off))); - auto llfn = cx.build.Load(llfnptr); - cx.build.FastCall(llfn, vec(cx.fcx.lltaskptr, llrawptr)); + + call_tydesc_glue_full(cx, bindings, cx.build.Load(tydescptr), + abi.tydesc_field_drop_glue_off); + // Then free the body. // FIXME: switch gc/non-gc on layer of the type. @@ -1469,15 +1472,28 @@ fn iter_sequence(@block_ctxt cx, fail; } +fn call_tydesc_glue_full(@block_ctxt cx, ValueRef v, + ValueRef tydesc, int field) { + auto llrawptr = cx.build.BitCast(v, T_ptr(T_i8())); + auto lltydescs = cx.build.GEP(tydesc, + vec(C_int(0), + C_int(abi.tydesc_field_first_param))); + lltydescs = cx.build.Load(lltydescs); + auto llfnptr = cx.build.GEP(tydesc, vec(C_int(0), C_int(field))); + auto llfn = cx.build.Load(llfnptr); + cx.build.FastCall(llfn, vec(cx.fcx.lltaskptr, lltydescs, llrawptr)); +} + +fn call_tydesc_glue(@block_ctxt cx, ValueRef v, @ty.t t, int field) { + call_tydesc_glue_full(cx, v, get_tydesc(cx, t), field); +} + fn incr_all_refcnts(@block_ctxt cx, ValueRef v, @ty.t t) -> result { if (!ty.type_is_scalar(t)) { - auto llrawptr = cx.build.BitCast(v, T_ptr(T_i8())); - auto llfnptr = field_of_tydesc(cx, t, abi.tydesc_field_take_glue_off); - auto llfn = cx.build.Load(llfnptr); - cx.build.FastCall(llfn, vec(cx.fcx.lltaskptr, llrawptr)); + call_tydesc_glue(cx, v, t, abi.tydesc_field_take_glue_off); } ret res(cx, C_nil()); } @@ -1499,10 +1515,7 @@ fn drop_ty(@block_ctxt cx, @ty.t t) -> result { if (!ty.type_is_scalar(t)) { - auto llrawptr = cx.build.BitCast(v, T_ptr(T_i8())); - auto llfnptr = field_of_tydesc(cx, t, abi.tydesc_field_drop_glue_off); - auto llfn = cx.build.Load(llfnptr); - cx.build.FastCall(llfn, vec(cx.fcx.lltaskptr, llrawptr)); + call_tydesc_glue(cx, v, t, abi.tydesc_field_drop_glue_off); } ret res(cx, C_nil()); } -- cgit v1.2.3