From b781c8b08e5b6b207c0422454ab8f319c90fe64d Mon Sep 17 00:00:00 2001 From: Ruud van Asseldonk Date: Mon, 10 Nov 2014 18:14:31 +0100 Subject: [PATCH] rustc: Unify fat pointer ABI constants. This merges the `trt_field_*`, `fn_field_*` and `slice_elt_*` constants into two `FAT_PTR_*` constants. This resolves the first part of #18590. --- src/librustc_back/abi.rs | 23 ++++++++++------------- src/librustc_trans/trans/_match.rs | 4 ++-- src/librustc_trans/trans/adt.rs | 8 ++++---- src/librustc_trans/trans/base.rs | 8 ++++---- src/librustc_trans/trans/callee.rs | 4 ++-- src/librustc_trans/trans/closure.rs | 4 ++-- src/librustc_trans/trans/consts.rs | 4 ++-- src/librustc_trans/trans/expr.rs | 4 ++-- src/librustc_trans/trans/glue.rs | 28 ++++++++++++++-------------- src/librustc_trans/trans/meth.rs | 8 ++++---- src/librustc_trans/trans/tvec.rs | 8 ++++---- 11 files changed, 50 insertions(+), 53 deletions(-) diff --git a/src/librustc_back/abi.rs b/src/librustc_back/abi.rs index 335317be4b4..f89d5d826f5 100644 --- a/src/librustc_back/abi.rs +++ b/src/librustc_back/abi.rs @@ -14,17 +14,14 @@ pub const box_field_refcnt: uint = 0u; pub const box_field_drop_glue: uint = 1u; pub const box_field_body: uint = 4u; -// FIXME(18590) although we have three different layouts here, the compiler relies on -// them being the same. We should replace them with one set of constants. +/// The first half of a fat pointer. +/// - For a closure, this is the code address. +/// - For an object or trait instance, this is the address of the box. +/// - For a slice, this is the base address. +pub const FAT_PTR_ADDR: uint = 0; -// The two halves of a closure: code and environment. -pub const fn_field_code: uint = 0u; -pub const fn_field_box: uint = 1u; - -// The two fields of a trait object/trait instance: vtable and box. -// The vtable contains the type descriptor as first element. -pub const trt_field_box: uint = 0u; -pub const trt_field_vtable: uint = 1u; - -pub const slice_elt_base: uint = 0u; -pub const slice_elt_len: uint = 1u; +/// The second half of a fat pointer. +/// - For a closure, this is the address of the environment. +/// - For an object or trait instance, this is the address of the vtable. +/// - For a slice, this is the length. +pub const FAT_PTR_EXTRA: uint = 1u; diff --git a/src/librustc_trans/trans/_match.rs b/src/librustc_trans/trans/_match.rs index de406cff6e7..d23e53d2e69 100644 --- a/src/librustc_trans/trans/_match.rs +++ b/src/librustc_trans/trans/_match.rs @@ -649,8 +649,8 @@ fn bind_subslice_pat(bcx: Block, ty::mt {ty: vt.unit_ty, mutbl: ast::MutImmutable}); let scratch = rvalue_scratch_datum(bcx, slice_ty, ""); Store(bcx, slice_begin, - GEPi(bcx, scratch.val, &[0u, abi::slice_elt_base])); - Store(bcx, slice_len, GEPi(bcx, scratch.val, &[0u, abi::slice_elt_len])); + GEPi(bcx, scratch.val, &[0u, abi::FAT_PTR_ADDR])); + Store(bcx, slice_len, GEPi(bcx, scratch.val, &[0u, abi::FAT_PTR_EXTRA])); scratch.val } diff --git a/src/librustc_trans/trans/adt.rs b/src/librustc_trans/trans/adt.rs index 2e184a5d74b..e7d1b9726a1 100644 --- a/src/librustc_trans/trans/adt.rs +++ b/src/librustc_trans/trans/adt.rs @@ -52,7 +52,7 @@ use std::num::Int; use std::rc::Rc; use llvm::{ValueRef, True, IntEQ, IntNE}; -use back::abi::slice_elt_base; +use back::abi; use middle::subst; use middle::subst::Subst; use trans::_match; @@ -684,7 +684,7 @@ fn struct_wrapped_nullable_bitdiscr(bcx: Block, nndiscr: Disr, ptrfield: Pointer scrutinee: ValueRef) -> ValueRef { let llptrptr = match ptrfield { ThinPointer(field) => GEPi(bcx, scrutinee, &[0, field]), - FatPointer(field) => GEPi(bcx, scrutinee, &[0, field, slice_elt_base]) + FatPointer(field) => GEPi(bcx, scrutinee, &[0, field, abi::FAT_PTR_ADDR]) }; let llptr = Load(bcx, llptrptr); let cmp = if nndiscr == 0 { IntEQ } else { IntNE }; @@ -782,7 +782,7 @@ pub fn trans_set_discr<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, r: &Repr<'tcx>, (GEPi(bcx, val, &[0, field]), type_of::type_of(bcx.ccx(), nonnull.fields[field])), FatPointer(field) => { - let v = GEPi(bcx, val, &[0, field, slice_elt_base]); + let v = GEPi(bcx, val, &[0, field, abi::FAT_PTR_ADDR]); (v, val_ty(v).element_type()) } }; @@ -1118,7 +1118,7 @@ pub fn const_get_discrim(ccx: &CrateContext, r: &Repr, val: ValueRef) StructWrappedNullablePointer { nndiscr, ptrfield, .. } => { let (idx, sub_idx) = match ptrfield { ThinPointer(field) => (field, None), - FatPointer(field) => (field, Some(slice_elt_base)) + FatPointer(field) => (field, Some(abi::FAT_PTR_ADDR)) }; if is_null(const_struct_field(ccx, val, idx, sub_idx)) { /* subtraction as uint is ok because nndiscr is either 0 or 1 */ diff --git a/src/librustc_trans/trans/base.rs b/src/librustc_trans/trans/base.rs index c30ad781cc9..a6f35c29662 100644 --- a/src/librustc_trans/trans/base.rs +++ b/src/librustc_trans/trans/base.rs @@ -705,8 +705,8 @@ pub fn iter_structural_ty<'a, 'blk, 'tcx>(cx: Block<'blk, 'tcx>, let (data_ptr, info) = if ty::type_is_sized(cx.tcx(), t) { (av, None) } else { - let data = GEPi(cx, av, &[0, abi::slice_elt_base]); - let info = GEPi(cx, av, &[0, abi::slice_elt_len]); + let data = GEPi(cx, av, &[0, abi::FAT_PTR_ADDR]); + let info = GEPi(cx, av, &[0, abi::FAT_PTR_EXTRA]); (Load(cx, data), Some(Load(cx, info))) }; @@ -724,8 +724,8 @@ pub fn iter_structural_ty<'a, 'blk, 'tcx>(cx: Block<'blk, 'tcx>, } else { let boxed_ty = ty::mk_open(cx.tcx(), field_ty); let scratch = datum::rvalue_scratch_datum(cx, boxed_ty, "__fat_ptr_iter"); - Store(cx, llfld_a, GEPi(cx, scratch.val, &[0, abi::slice_elt_base])); - Store(cx, info.unwrap(), GEPi(cx, scratch.val, &[0, abi::slice_elt_len])); + Store(cx, llfld_a, GEPi(cx, scratch.val, &[0, abi::FAT_PTR_ADDR])); + Store(cx, info.unwrap(), GEPi(cx, scratch.val, &[0, abi::FAT_PTR_EXTRA])); scratch.val }; cx = f(cx, val, field_ty); diff --git a/src/librustc_trans/trans/callee.rs b/src/librustc_trans/trans/callee.rs index bf7adbbecef..6d0f5980442 100644 --- a/src/librustc_trans/trans/callee.rs +++ b/src/librustc_trans/trans/callee.rs @@ -724,9 +724,9 @@ pub fn trans_call_inner<'a, 'blk, 'tcx>(bcx: Block<'blk, 'tcx>, // Closures are represented as (llfn, llclosure) pair: // load the requisite values out. let pair = d.to_llref(); - let llfn = GEPi(bcx, pair, &[0u, abi::fn_field_code]); + let llfn = GEPi(bcx, pair, &[0u, abi::FAT_PTR_ADDR]); let llfn = Load(bcx, llfn); - let llenv = GEPi(bcx, pair, &[0u, abi::fn_field_box]); + let llenv = GEPi(bcx, pair, &[0u, abi::FAT_PTR_EXTRA]); let llenv = Load(bcx, llenv); (llfn, Some(llenv), None) } diff --git a/src/librustc_trans/trans/closure.rs b/src/librustc_trans/trans/closure.rs index d4c93be7eaf..c0c46ed57cc 100644 --- a/src/librustc_trans/trans/closure.rs +++ b/src/librustc_trans/trans/closure.rs @@ -339,9 +339,9 @@ fn load_unboxed_closure_environment<'blk, 'tcx>( } fn fill_fn_pair(bcx: Block, pair: ValueRef, llfn: ValueRef, llenvptr: ValueRef) { - Store(bcx, llfn, GEPi(bcx, pair, &[0u, abi::fn_field_code])); + Store(bcx, llfn, GEPi(bcx, pair, &[0u, abi::FAT_PTR_ADDR])); let llenvptr = PointerCast(bcx, llenvptr, Type::i8p(bcx.ccx())); - Store(bcx, llenvptr, GEPi(bcx, pair, &[0u, abi::fn_field_box])); + Store(bcx, llenvptr, GEPi(bcx, pair, &[0u, abi::FAT_PTR_EXTRA])); } #[deriving(PartialEq)] diff --git a/src/librustc_trans/trans/consts.rs b/src/librustc_trans/trans/consts.rs index 4213e941727..c119cf16328 100644 --- a/src/librustc_trans/trans/consts.rs +++ b/src/librustc_trans/trans/consts.rs @@ -264,8 +264,8 @@ pub fn const_expr<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, e: &ast::Expr) ty::ty_vec(unit_ty, Some(len)) => { let llunitty = type_of::type_of(cx, unit_ty); let llptr = const_ptrcast(cx, llconst, llunitty); - assert_eq!(abi::slice_elt_base, 0); - assert_eq!(abi::slice_elt_len, 1); + assert_eq!(abi::FAT_PTR_ADDR, 0); + assert_eq!(abi::FAT_PTR_EXTRA, 1); llconst = C_struct(cx, &[ llptr, C_uint(cx, len) diff --git a/src/librustc_trans/trans/expr.rs b/src/librustc_trans/trans/expr.rs index 670e893cc0e..b4751578dd1 100644 --- a/src/librustc_trans/trans/expr.rs +++ b/src/librustc_trans/trans/expr.rs @@ -171,11 +171,11 @@ pub fn trans<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, } pub fn get_len(bcx: Block, fat_ptr: ValueRef) -> ValueRef { - GEPi(bcx, fat_ptr, &[0u, abi::slice_elt_len]) + GEPi(bcx, fat_ptr, &[0u, abi::FAT_PTR_EXTRA]) } pub fn get_dataptr(bcx: Block, fat_ptr: ValueRef) -> ValueRef { - GEPi(bcx, fat_ptr, &[0u, abi::slice_elt_base]) + GEPi(bcx, fat_ptr, &[0u, abi::FAT_PTR_ADDR]) } fn apply_adjustments<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, diff --git a/src/librustc_trans/trans/glue.rs b/src/librustc_trans/trans/glue.rs index 67b3310dbdf..f4799d7536d 100644 --- a/src/librustc_trans/trans/glue.rs +++ b/src/librustc_trans/trans/glue.rs @@ -196,7 +196,7 @@ fn trans_struct_drop_flag<'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>, let struct_data = if ty::type_is_sized(bcx.tcx(), t) { v0 } else { - let llval = GEPi(bcx, v0, &[0, abi::slice_elt_base]); + let llval = GEPi(bcx, v0, &[0, abi::FAT_PTR_ADDR]); Load(bcx, llval) }; let drop_flag = unpack_datum!(bcx, adt::trans_drop_flag_ptr(bcx, &*repr, struct_data)); @@ -237,8 +237,8 @@ fn trans_struct_drop<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, let (struct_data, info) = if ty::type_is_sized(bcx.tcx(), t) { (v0, None) } else { - let data = GEPi(bcx, v0, &[0, abi::slice_elt_base]); - let info = GEPi(bcx, v0, &[0, abi::slice_elt_len]); + let data = GEPi(bcx, v0, &[0, abi::FAT_PTR_ADDR]); + let info = GEPi(bcx, v0, &[0, abi::FAT_PTR_EXTRA]); (Load(bcx, data), Some(Load(bcx, info))) }; @@ -255,14 +255,14 @@ fn trans_struct_drop<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, // The dtor expects a fat pointer, so make one, even if we have to fake it. let boxed_ty = ty::mk_open(bcx.tcx(), t); let scratch = datum::rvalue_scratch_datum(bcx, boxed_ty, "__fat_ptr_drop_self"); - Store(bcx, value, GEPi(bcx, scratch.val, &[0, abi::slice_elt_base])); + Store(bcx, value, GEPi(bcx, scratch.val, &[0, abi::FAT_PTR_ADDR])); Store(bcx, // If we just had a thin pointer, make a fat pointer by sticking // null where we put the unsizing info. This works because t // is a sized type, so we will only unpack the fat pointer, never // use the fake info. info.unwrap_or(C_null(Type::i8p(bcx.ccx()))), - GEPi(bcx, scratch.val, &[0, abi::slice_elt_len])); + GEPi(bcx, scratch.val, &[0, abi::FAT_PTR_EXTRA])); PointerCast(variant_cx, scratch.val, params[0]) } else { PointerCast(variant_cx, value, params[0]) @@ -280,8 +280,8 @@ fn trans_struct_drop<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, } else { let boxed_ty = ty::mk_open(bcx.tcx(), *ty); let scratch = datum::rvalue_scratch_datum(bcx, boxed_ty, "__fat_ptr_drop_field"); - Store(bcx, llfld_a, GEPi(bcx, scratch.val, &[0, abi::slice_elt_base])); - Store(bcx, info.unwrap(), GEPi(bcx, scratch.val, &[0, abi::slice_elt_len])); + Store(bcx, llfld_a, GEPi(bcx, scratch.val, &[0, abi::FAT_PTR_ADDR])); + Store(bcx, info.unwrap(), GEPi(bcx, scratch.val, &[0, abi::FAT_PTR_EXTRA])); scratch.val }; variant_cx.fcx.schedule_drop_mem(cleanup::CustomScope(field_scope), @@ -369,11 +369,11 @@ fn make_drop_glue<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, v0: ValueRef, t: Ty<'tcx>) tvec::make_drop_glue_unboxed(bcx, v0, unit_ty, true) } ty::ty_trait(..) => { - let lluniquevalue = GEPi(bcx, v0, &[0, abi::trt_field_box]); + let lluniquevalue = GEPi(bcx, v0, &[0, abi::FAT_PTR_ADDR]); // Only drop the value when it is non-null let concrete_ptr = Load(bcx, lluniquevalue); with_cond(bcx, IsNotNull(bcx, concrete_ptr), |bcx| { - let dtor_ptr = Load(bcx, GEPi(bcx, v0, &[0, abi::trt_field_vtable])); + let dtor_ptr = Load(bcx, GEPi(bcx, v0, &[0, abi::FAT_PTR_EXTRA])); let dtor = Load(bcx, dtor_ptr); Call(bcx, dtor, @@ -383,12 +383,12 @@ fn make_drop_glue<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, v0: ValueRef, t: Ty<'tcx>) }) } ty::ty_struct(..) if !ty::type_is_sized(bcx.tcx(), content_ty) => { - let llval = GEPi(bcx, v0, &[0, abi::slice_elt_base]); + let llval = GEPi(bcx, v0, &[0, abi::FAT_PTR_ADDR]); let llbox = Load(bcx, llval); let not_null = IsNotNull(bcx, llbox); with_cond(bcx, not_null, |bcx| { let bcx = drop_ty(bcx, v0, content_ty, None); - let info = GEPi(bcx, v0, &[0, abi::slice_elt_len]); + let info = GEPi(bcx, v0, &[0, abi::FAT_PTR_EXTRA]); let info = Load(bcx, info); let (llsize, llalign) = size_and_align_of_dst(bcx, content_ty, info); trans_exchange_free_dyn(bcx, llbox, llsize, llalign) @@ -440,7 +440,7 @@ fn make_drop_glue<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, v0: ValueRef, t: Ty<'tcx>) t, |bb, vv, tt| drop_ty(bb, vv, tt, None)), ty::ty_closure(ref f) if f.store == ty::UniqTraitStore => { - let box_cell_v = GEPi(bcx, v0, &[0u, abi::fn_field_box]); + let box_cell_v = GEPi(bcx, v0, &[0u, abi::FAT_PTR_EXTRA]); let env = Load(bcx, box_cell_v); let env_ptr_ty = Type::at_box(bcx.ccx(), Type::i8(bcx.ccx())).ptr_to(); let env = PointerCast(bcx, env, env_ptr_ty); @@ -456,8 +456,8 @@ fn make_drop_glue<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, v0: ValueRef, t: Ty<'tcx>) // above), because this happens for a trait field in an unsized // struct. If anything is null, it is the whole struct and we won't // get here. - let lluniquevalue = GEPi(bcx, v0, &[0, abi::trt_field_box]); - let dtor_ptr = Load(bcx, GEPi(bcx, v0, &[0, abi::trt_field_vtable])); + let lluniquevalue = GEPi(bcx, v0, &[0, abi::FAT_PTR_ADDR]); + let dtor_ptr = Load(bcx, GEPi(bcx, v0, &[0, abi::FAT_PTR_EXTRA])); let dtor = Load(bcx, dtor_ptr); Call(bcx, dtor, diff --git a/src/librustc_trans/trans/meth.rs b/src/librustc_trans/trans/meth.rs index 0311d37c3de..0ff7f3ee71c 100644 --- a/src/librustc_trans/trans/meth.rs +++ b/src/librustc_trans/trans/meth.rs @@ -481,7 +481,7 @@ pub fn trans_trait_callee_from_llval<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, // Load the data pointer from the object. debug!("(translating trait callee) loading second index from pair"); - let llboxptr = GEPi(bcx, llpair, &[0u, abi::trt_field_box]); + let llboxptr = GEPi(bcx, llpair, &[0u, abi::FAT_PTR_ADDR]); let llbox = Load(bcx, llboxptr); let llself = PointerCast(bcx, llbox, Type::i8p(ccx)); @@ -503,7 +503,7 @@ pub fn trans_trait_callee_from_llval<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, let llvtable = Load(bcx, PointerCast(bcx, GEPi(bcx, llpair, - &[0u, abi::trt_field_vtable]), + &[0u, abi::FAT_PTR_EXTRA]), Type::vtable(ccx).ptr_to().ptr_to())); let mptr = Load(bcx, GEPi(bcx, llvtable, &[0u, n_method + VTABLE_OFFSET])); let mptr = PointerCast(bcx, mptr, llcallee_ty.ptr_to()); @@ -761,13 +761,13 @@ pub fn trans_trait_cast<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, let llbox_ty = type_of(bcx.ccx(), datum_ty); // Store the pointer into the first half of pair. - let llboxdest = GEPi(bcx, lldest, &[0u, abi::trt_field_box]); + let llboxdest = GEPi(bcx, lldest, &[0u, abi::FAT_PTR_ADDR]); let llboxdest = PointerCast(bcx, llboxdest, llbox_ty.ptr_to()); bcx = datum.store_to(bcx, llboxdest); // Store the vtable into the second half of pair. let vtable = get_vtable(bcx, datum_ty, trait_ref); - let llvtabledest = GEPi(bcx, lldest, &[0u, abi::trt_field_vtable]); + let llvtabledest = GEPi(bcx, lldest, &[0u, abi::FAT_PTR_EXTRA]); let llvtabledest = PointerCast(bcx, llvtabledest, val_ty(vtable).ptr_to()); Store(bcx, vtable, llvtabledest); diff --git a/src/librustc_trans/trans/tvec.rs b/src/librustc_trans/trans/tvec.rs index 359f74bdbf1..8e986defb6a 100644 --- a/src/librustc_trans/trans/tvec.rs +++ b/src/librustc_trans/trans/tvec.rs @@ -231,8 +231,8 @@ pub fn trans_lit_str<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, let llbytes = C_uint(bcx.ccx(), bytes); let llcstr = C_cstr(bcx.ccx(), str_lit, false); let llcstr = llvm::LLVMConstPointerCast(llcstr, Type::i8p(bcx.ccx()).to_ref()); - Store(bcx, llcstr, GEPi(bcx, lldest, &[0u, abi::slice_elt_base])); - Store(bcx, llbytes, GEPi(bcx, lldest, &[0u, abi::slice_elt_len])); + Store(bcx, llcstr, GEPi(bcx, lldest, &[0u, abi::FAT_PTR_ADDR])); + Store(bcx, llbytes, GEPi(bcx, lldest, &[0u, abi::FAT_PTR_EXTRA])); bcx } } @@ -401,8 +401,8 @@ pub fn get_fixed_base_and_len(bcx: Block, fn get_slice_base_and_len(bcx: Block, llval: ValueRef) -> (ValueRef, ValueRef) { - let base = Load(bcx, GEPi(bcx, llval, &[0u, abi::slice_elt_base])); - let len = Load(bcx, GEPi(bcx, llval, &[0u, abi::slice_elt_len])); + let base = Load(bcx, GEPi(bcx, llval, &[0u, abi::FAT_PTR_ADDR])); + let len = Load(bcx, GEPi(bcx, llval, &[0u, abi::FAT_PTR_EXTRA])); (base, len) }