diff --git a/src/comp/back/abi.rs b/src/comp/back/abi.rs index d65a9049786..6a53767491f 100644 --- a/src/comp/back/abi.rs +++ b/src/comp/back/abi.rs @@ -47,30 +47,21 @@ const vec_elt_pad: int = 3; const vec_elt_data: int = 4; const tydesc_field_first_param: int = 0; - const tydesc_field_size: int = 1; - const tydesc_field_align: int = 2; - const tydesc_field_copy_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_is_stateful: int = 9; - const tydesc_field_cmp_glue: int = 10; - -const n_tydesc_fields: int = 11; +const tydesc_field_shape: int = 11; +const tydesc_field_shape_tables: int = 12; +const tydesc_field_n_params: int = 13; +const n_tydesc_fields: int = 14; const cmp_glue_op_eq: uint = 0u; diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs index 817e82718ec..91218fb95ad 100644 --- a/src/comp/middle/trans.rs +++ b/src/comp/middle/trans.rs @@ -895,7 +895,8 @@ fn linearize_ty_params(cx: &@block_ctxt, t: &ty::t) -> fn trans_stack_local_derived_tydesc(cx: &@block_ctxt, llsz: ValueRef, llalign: ValueRef, llroottydesc: ValueRef, - llparamtydescs: ValueRef) -> ValueRef { + llparamtydescs: ValueRef, + n_params: uint) -> ValueRef { let llmyroottydesc = alloca(cx, bcx_ccx(cx).tydesc_type); // By convention, desc 0 is the root descriptor. @@ -904,11 +905,14 @@ fn trans_stack_local_derived_tydesc(cx: &@block_ctxt, llsz: ValueRef, // Store a pointer to the rest of the descriptors. let llfirstparam = cx.build.GEP(llparamtydescs, ~[C_int(0), C_int(0)]); - cx.build.Store(llfirstparam, - cx.build.GEP(llmyroottydesc, ~[C_int(0), C_int(0)])); - cx.build.Store(llsz, cx.build.GEP(llmyroottydesc, ~[C_int(0), C_int(1)])); - cx.build.Store(llalign, - cx.build.GEP(llmyroottydesc, ~[C_int(0), C_int(2)])); + store_inbounds(cx, llfirstparam, llmyroottydesc, + ~[C_int(0), C_int(abi::tydesc_field_first_param)]); + store_inbounds(cx, C_uint(n_params), llmyroottydesc, + ~[C_int(0), C_int(abi::tydesc_field_n_params)]); + store_inbounds(cx, llsz, llmyroottydesc, + ~[C_int(0), C_int(abi::tydesc_field_size)]); + store_inbounds(cx, llalign, llmyroottydesc, + ~[C_int(0), C_int(abi::tydesc_field_align)]); ret llmyroottydesc; } @@ -964,7 +968,8 @@ fn get_derived_tydesc(cx: &@block_ctxt, t: &ty::t, escapes: bool, v = td_val; } else { let llparamtydescs = - alloca(bcx, T_array(T_ptr(bcx_ccx(bcx).tydesc_type), n_params)); + alloca(bcx, T_array(T_ptr(bcx_ccx(bcx).tydesc_type), + n_params + 1u)); let i = 0; for td: ValueRef in tys.descs { let tdp = bcx.build.GEP(llparamtydescs, ~[C_int(0), C_int(i)]); @@ -973,7 +978,7 @@ fn get_derived_tydesc(cx: &@block_ctxt, t: &ty::t, escapes: bool, } v = trans_stack_local_derived_tydesc(bcx, sz.val, align.val, root, - llparamtydescs); + llparamtydescs, n_params); } bcx.fcx.derived_tydescs.insert(t, {lltydesc: v, escapes: escapes}); ret rslt(cx, v); @@ -1191,20 +1196,28 @@ 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 - // drop_glue - // free_glue - // sever_glue - // mark_glue - // obj_drop_glue - // is_stateful - tydesc = + + let shape = shape::shape_of(ccx, pair.key); + let shape_tables = + llvm::LLVMConstPointerCast(ccx.shape_cx.llshapetables, + T_ptr(T_i8())); + + let tydesc = C_named_struct(ccx.tydesc_type, - ~[C_null(T_ptr(T_ptr(ccx.tydesc_type))), ti.size, - ti.align, copy_glue, drop_glue, free_glue, - C_null(glue_fn_ty), C_null(glue_fn_ty), - C_null(glue_fn_ty), C_null(glue_fn_ty), - cmp_glue]); // cmp_glue + ~[C_null(T_ptr(T_ptr(ccx.tydesc_type))), + ti.size, // size + ti.align, // align + copy_glue, // copy_glue + drop_glue, // drop_glue + free_glue, // free_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 + shape_tables, // shape_tables + C_int(0)]); // n_params let gvar = ti.tydesc; llvm::LLVMSetInitializer(gvar, tydesc); @@ -2288,8 +2301,9 @@ fn call_cmp_glue(cx: &@block_ctxt, lhs: ValueRef, rhs: ValueRef, t: &ty::t, let ti = none[@tydesc_info]; let r = get_tydesc(cx, t, false, ti); lazily_emit_tydesc_glue(cx, abi::tydesc_field_cmp_glue, ti); + let lltydesc = r.val; let lltydescs = - r.bcx.build.GEP(r.val, + r.bcx.build.GEP(lltydesc, ~[C_int(0), C_int(abi::tydesc_field_first_param)]); lltydescs = r.bcx.build.Load(lltydescs); @@ -2297,7 +2311,7 @@ fn call_cmp_glue(cx: &@block_ctxt, lhs: ValueRef, rhs: ValueRef, t: &ty::t, alt ti { none. { let llfnptr = - r.bcx.build.GEP(r.val, + r.bcx.build.GEP(lltydesc, ~[C_int(0), C_int(abi::tydesc_field_cmp_glue)]); llfn = r.bcx.build.Load(llfnptr); } @@ -2306,7 +2320,7 @@ fn call_cmp_glue(cx: &@block_ctxt, lhs: ValueRef, rhs: ValueRef, t: &ty::t, let llcmpresultptr = alloca(r.bcx, T_i1()); let llargs: ValueRef[] = - ~[llcmpresultptr, r.bcx.fcx.lltaskptr, C_null(T_ptr(T_nil())), + ~[llcmpresultptr, r.bcx.fcx.lltaskptr, lltydesc, lltydescs, llrawlhsptr, llrawrhsptr, llop]; r.bcx.build.Call(llfn, llargs); ret rslt(r.bcx, r.bcx.build.Load(llcmpresultptr)); @@ -8000,8 +8014,9 @@ fn trans_crate(sess: &session::session, crate: &@ast::crate, tcx: &ty::ctxt, trans_mod(cx, crate.node.module); create_crate_map(ccx); emit_tydescs(ccx); - // Translate the metadata: + shape::gen_shape_tables(ccx); + // Translate the metadata. write_metadata(cx.ccx, crate); if ccx.sess.get_opts().stats { log_err "--- trans stats ---"; diff --git a/src/comp/middle/trans_common.rs b/src/comp/middle/trans_common.rs index 32b25a8a062..e0b26a97c9f 100644 --- a/src/comp/middle/trans_common.rs +++ b/src/comp/middle/trans_common.rs @@ -597,22 +597,13 @@ fn T_tydesc(taskptr_type: TypeRef) -> TypeRef { T_ptr(T_fn(~[T_ptr(T_nil()), taskptr_type, T_ptr(T_nil()), tydescpp, pvoid], T_void())); let cmp_glue_fn_ty = - T_ptr(T_fn(~[T_ptr(T_i1()), taskptr_type, T_ptr(T_nil()), tydescpp, + T_ptr(T_fn(~[T_ptr(T_i1()), taskptr_type, T_ptr(tydesc), tydescpp, pvoid, pvoid, T_i8()], T_void())); - let // first_param - // size - // align - // copy_glue - // drop_glue - // free_glue - // sever_glue - // mark_glue - // obj_drop_glue - // is_stateful - elems = + 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]; + 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; } @@ -874,3 +865,14 @@ fn C_bytes(bytes : &u8[]) -> ValueRef { ivec::len(bytes), False); } +fn C_shape(ccx : &@crate_ctxt, bytes : &u8[]) -> ValueRef { + let llshape = C_bytes(bytes); + let llglobal = llvm::LLVMAddGlobal(ccx.llmod, val_ty(llshape), + str::buf(ccx.names.next("shape"))); + llvm::LLVMSetInitializer(llglobal, llshape); + llvm::LLVMSetGlobalConstant(llglobal, True); + llvm::LLVMSetLinkage(llglobal, + lib::llvm::LLVMInternalLinkage as llvm::Linkage); + ret llvm::LLVMConstPointerCast(llglobal, T_ptr(T_i8())); +} +