From dcd84901c674eda61fefc363a0adc44790b4e24f Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Wed, 29 May 2013 15:49:23 -0400 Subject: [PATCH] Remove TrByImplicitRef and source field on datums --- src/librustc/middle/trans/_match.rs | 20 ++--- src/librustc/middle/trans/callee.rs | 5 +- src/librustc/middle/trans/closure.rs | 4 +- src/librustc/middle/trans/datum.rs | 128 ++++++++++++--------------- src/librustc/middle/trans/expr.rs | 20 ++--- src/librustc/middle/trans/foreign.rs | 20 ++--- src/librustc/middle/trans/meth.rs | 4 +- 7 files changed, 86 insertions(+), 115 deletions(-) diff --git a/src/librustc/middle/trans/_match.rs b/src/librustc/middle/trans/_match.rs index ca7ce9c02d1..22a487a4114 100644 --- a/src/librustc/middle/trans/_match.rs +++ b/src/librustc/middle/trans/_match.rs @@ -314,7 +314,6 @@ pub fn variant_opt(bcx: block, pat_id: ast::node_id) pub enum TransBindingMode { TrByValue(/*ismove:*/ bool, /*llbinding:*/ ValueRef), TrByRef, - TrByImplicitRef } /** @@ -881,7 +880,7 @@ fn match_datum(bcx: block, val: ValueRef, pat_id: ast::node_id) -> Datum { //! we should just pass around a Datum and be done with it. let ty = node_id_type(bcx, pat_id); - Datum {val: val, ty: ty, mode: datum::ByRef, source: RevokeClean} + Datum {val: val, ty: ty, mode: datum::ByRef(RevokeClean)} } @@ -988,7 +987,7 @@ pub fn root_pats_as_necessary(mut bcx: block, let pat_id = br.pats[col].id; if pat_id != 0 { let datum = Datum {val: val, ty: node_id_type(bcx, pat_id), - mode: ByRef, source: ZeroMem}; + mode: ByRef(ZeroMem)}; bcx = datum.root_and_write_guard(bcx, br.pats[col].span, pat_id, 0); } } @@ -1146,7 +1145,7 @@ pub fn store_non_ref_bindings(bcx: block, TrByValue(is_move, lldest) => { let llval = Load(bcx, binding_info.llmatch); // get a T* let datum = Datum {val: llval, ty: binding_info.ty, - mode: ByRef, source: ZeroMem}; + mode: ByRef(ZeroMem)}; bcx = { if is_move { datum.move_to(bcx, INIT, lldest) @@ -1161,7 +1160,7 @@ pub fn store_non_ref_bindings(bcx: block, temp_cleanups } } - TrByRef | TrByImplicitRef => {} + TrByRef => {} } } return bcx; @@ -1192,13 +1191,6 @@ pub fn insert_lllocals(bcx: block, TrByRef => { binding_info.llmatch } - - // Ugly: for implicit ref, we actually want a T*, but - // we have a T**, so we had to load. This will go away - // once implicit refs go away. - TrByImplicitRef => { - Load(bcx, binding_info.llmatch) - } }; bcx.fcx.lllocals.insert(binding_info.id, @@ -1254,7 +1246,7 @@ pub fn compile_guard(bcx: block, TrByValue(_, llval) => { bcx = glue::drop_ty(bcx, llval, binding_info.ty); } - TrByRef | TrByImplicitRef => {} + TrByRef => {} } bcx.fcx.lllocals.remove(&binding_info.id); } @@ -1757,7 +1749,7 @@ pub fn bind_irrefutable_pat(bcx: block, if make_copy { let binding_ty = node_id_type(bcx, pat.id); let datum = Datum {val: val, ty: binding_ty, - mode: ByRef, source: RevokeClean}; + mode: ByRef(RevokeClean)}; let scratch = scratch_datum(bcx, binding_ty, false); datum.copy_to_datum(bcx, INIT, scratch); match binding_mode { diff --git a/src/librustc/middle/trans/callee.rs b/src/librustc/middle/trans/callee.rs index 1e6e31e4277..557388cf11c 100644 --- a/src/librustc/middle/trans/callee.rs +++ b/src/librustc/middle/trans/callee.rs @@ -711,8 +711,7 @@ pub fn trans_arg_expr(bcx: block, DatumBlock {bcx: bcx, datum: Datum {val: scratch, ty: scratch_ty, - mode: ByRef, - source: RevokeClean}} + mode: ByRef(RevokeClean)}} } _ => { bcx.sess().impossible_case( @@ -775,7 +774,7 @@ pub fn trans_arg_expr(bcx: block, match arg_datum.appropriate_mode() { ByValue => val = Load(bcx, scratch.val), - ByRef => val = scratch.val, + ByRef(_) => val = scratch.val, } } } diff --git a/src/librustc/middle/trans/closure.rs b/src/librustc/middle/trans/closure.rs index fa3e6eeb0b6..1a78019f289 100644 --- a/src/librustc/middle/trans/closure.rs +++ b/src/librustc/middle/trans/closure.rs @@ -287,7 +287,7 @@ pub fn build_closure(bcx0: block, for include_ret_handle.each |flagptr| { // Flag indicating we have returned (a by-ref bool): let flag_datum = Datum {val: *flagptr, ty: ty::mk_bool(), - mode: ByRef, source: ZeroMem}; + mode: ByRef(ZeroMem)}; env_vals.push(EnvValue {action: EnvRef, datum: flag_datum}); @@ -299,7 +299,7 @@ pub fn build_closure(bcx0: block, }; let ret_casted = PointerCast(bcx, ret_true, T_ptr(T_nil())); let ret_datum = Datum {val: ret_casted, ty: ty::mk_nil(), - mode: ByRef, source: ZeroMem}; + mode: ByRef(ZeroMem)}; env_vals.push(EnvValue {action: EnvRef, datum: ret_datum}); } diff --git a/src/librustc/middle/trans/datum.rs b/src/librustc/middle/trans/datum.rs index c8b9e3f8f0e..692fbf47957 100644 --- a/src/librustc/middle/trans/datum.rs +++ b/src/librustc/middle/trans/datum.rs @@ -44,15 +44,17 @@ * # Datum cleanup styles * * Each datum carries with it an idea of how its value will be cleaned - * up. This is important after a move, because we need to know how to - * cancel the cleanup (since the value has been moved and therefore does - * not need to be freed). There are two options: - * - * 1. `RevokeClean`: To cancel the cleanup, we invoke `revoke_clean()`. - * This is used for temporary rvalues. - * - * 2. `ZeroMem`: To cancel the cleanup, we zero out the memory where - * the value resides. This is used for lvalues. + * up. This is primarily determined by the mode: a `ByValue` datum + * will always be cleaned up by revoking cleanup using + * `revoke_clean()`, because there is no other option. By ref datums + * can sometimes be cleaned up via `revoke_clean` (in particular, + * by-ref datums that originated from rvalues), but sometimes they + * must be zeroed. This is indicated by the `DatumCleanup` + * parameter. Note that zeroing a by-ref datum *always works* to + * cancel the cleanup, but using `revoke_clean` is preferable since + * there is no runtime cost. Some older parts of the code (notably + * `match_`, at least at the time of this writing) rely on this and + * only use zeroing. * * # Copying, moving, and storing * @@ -125,12 +127,6 @@ pub struct Datum { /// Indicates whether this is by-ref or by-value. mode: DatumMode, - - /// How did this value originate? This is particularly important - /// if the value is MOVED or prematurely DROPPED, because it - /// describes how to cancel the cleanup that was scheduled before. - /// See the def'n of the `DatumCleanup` type. - source: DatumCleanup } pub struct DatumBlock { @@ -138,10 +134,13 @@ pub struct DatumBlock { datum: Datum, } -#[deriving(Eq)] +#[deriving(Eq, IterBytes)] pub enum DatumMode { - /// `val` is a pointer to the actual value (and thus has type *T) - ByRef, + /// `val` is a pointer to the actual value (and thus has type *T). + /// The argument indicates how to cancel cleanup of this datum if + /// the value is moved elsewhere, which can either be by zeroing + /// the memory or by canceling a registered cleanup. + ByRef(DatumCleanup), /// `val` is the actual value (*only used for immediates* like ints, ptrs) ByValue, @@ -149,30 +148,23 @@ pub enum DatumMode { pub impl DatumMode { fn is_by_ref(&self) -> bool { - match *self { ByRef => true, ByValue => false } + match *self { ByRef(_) => true, ByValue => false } } fn is_by_value(&self) -> bool { - match *self { ByRef => false, ByValue => true } - } -} - -impl to_bytes::IterBytes for DatumMode { - fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) -> bool { - (*self as uint).iter_bytes(lsb0, f) + match *self { ByRef(_) => false, ByValue => true } } } /// See `Datum cleanup styles` section at the head of this module. -#[deriving(Eq)] +#[deriving(Eq, IterBytes)] pub enum DatumCleanup { RevokeClean, ZeroMem } pub fn immediate_rvalue(val: ValueRef, ty: ty::t) -> Datum { - return Datum {val: val, ty: ty, - mode: ByValue, source: RevokeClean}; + return Datum {val: val, ty: ty, mode: ByValue}; } pub fn immediate_rvalue_bcx(bcx: block, @@ -195,7 +187,7 @@ pub fn scratch_datum(bcx: block, ty: ty::t, zero: bool) -> Datum { let llty = type_of::type_of(bcx.ccx(), ty); let scratch = alloca_maybe_zeroed(bcx, llty, zero); - Datum { val: scratch, ty: ty, mode: ByRef, source: RevokeClean } + Datum { val: scratch, ty: ty, mode: ByRef(RevokeClean) } } pub fn appropriate_mode(ty: ty::t) -> DatumMode { @@ -210,7 +202,7 @@ pub fn appropriate_mode(ty: ty::t) -> DatumMode { } else if ty::type_is_immediate(ty) { ByValue } else { - ByRef + ByRef(RevokeClean) } } @@ -289,7 +281,7 @@ pub impl Datum { ty::type_needs_drop(bcx.tcx(), self.ty) { match self.mode { - ByRef => { + ByRef(_) => { let cast = PointerCast(bcx, dst, val_ty(self.val)); let cmp = ICmp(bcx, lib::llvm::IntNE, cast, self.val); do with_cond(bcx, cmp) |bcx| { @@ -324,7 +316,7 @@ pub impl Datum { ByValue => { Store(bcx, self.val, dst); } - ByRef => { + ByRef(_) => { memcpy_ty(bcx, dst, self.val, self.ty); } } @@ -352,7 +344,7 @@ pub impl Datum { } match self.mode { - ByRef => { + ByRef(_) => { memcpy_ty(bcx, dst, self.val, self.ty); } ByValue => { @@ -367,28 +359,32 @@ pub impl Datum { fn add_clean(&self, bcx: block) { /*! - * * Schedules this datum for cleanup in `bcx`. The datum - * must be an rvalue. */ + * must be an rvalue. + */ - assert_eq!(self.source, RevokeClean); match self.mode { ByValue => { add_clean_temp_immediate(bcx, self.val, self.ty); } - ByRef => { + ByRef(RevokeClean) => { add_clean_temp_mem(bcx, self.val, self.ty); } + ByRef(ZeroMem) => { + bcx.tcx().sess.bug( + fmt!("Cannot add clean to a 'zero-mem' datum")); + } } } fn cancel_clean(&self, bcx: block) { if ty::type_needs_drop(bcx.tcx(), self.ty) { - match self.source { - RevokeClean => { + match self.mode { + ByValue | + ByRef(RevokeClean) => { revoke_clean(bcx, self.val); } - ZeroMem => { + ByRef(ZeroMem) => { // Lvalues which potentially need to be dropped // must be passed by ref, so that we can zero them // out. @@ -400,11 +396,10 @@ pub impl Datum { } fn to_str(&self, ccx: &CrateContext) -> ~str { - fmt!("Datum { val=%s, ty=%s, mode=%?, source=%? }", + fmt!("Datum { val=%s, ty=%s, mode=%? }", val_str(ccx.tn, self.val), ty_to_str(ccx.tcx, self.ty), - self.mode, - self.source) + self.mode) } fn to_value_datum(&self, bcx: block) -> Datum { @@ -417,9 +412,9 @@ pub impl Datum { match self.mode { ByValue => *self, - ByRef => { + ByRef(_) => { Datum {val: self.to_value_llval(bcx), mode: ByValue, - ty: self.ty, source: RevokeClean} + ty: self.ty} } } } @@ -434,7 +429,7 @@ pub impl Datum { } else { match self.mode { ByValue => self.val, - ByRef => { + ByRef(_) => { if ty::type_is_bool(self.ty) { LoadRangeAssert(bcx, self.val, 0, 2, lib::llvm::True) } else { @@ -447,24 +442,24 @@ pub impl Datum { fn to_ref_datum(&self, bcx: block) -> Datum { /*! - * * Yields a by-ref form of this datum. This may involve * creation of a temporary stack slot. The value returned by * this function is not separately rooted from this datum, so - * it will not live longer than the current datum. */ + * it will not live longer than the current datum. + */ match self.mode { - ByRef => *self, + ByRef(_) => *self, ByValue => { - Datum {val: self.to_ref_llval(bcx), mode: ByRef, - ty: self.ty, source: RevokeClean} + Datum {val: self.to_ref_llval(bcx), mode: ByRef(RevokeClean), + ty: self.ty} } } } fn to_ref_llval(&self, bcx: block) -> ValueRef { match self.mode { - ByRef => self.val, + ByRef(_) => self.val, ByValue => { if ty::type_is_nil(self.ty) || ty::type_is_bot(self.ty) { C_null(T_ptr(type_of::type_of(bcx.ccx(), self.ty))) @@ -490,7 +485,7 @@ pub impl Datum { match self.appropriate_mode() { ByValue => self.to_value_llval(bcx), - ByRef => self.to_ref_llval(bcx) + ByRef(_) => self.to_ref_llval(bcx) } } @@ -501,7 +496,7 @@ pub impl Datum { match self.appropriate_mode() { ByValue => self.to_value_datum(bcx), - ByRef => self.to_ref_datum(bcx) + ByRef(_) => self.to_ref_datum(bcx) } } @@ -512,9 +507,8 @@ pub impl Datum { let base_val = self.to_ref_llval(bcx); Datum { val: gep(base_val), - mode: ByRef, + mode: ByRef(source), ty: ty, - source: source } } @@ -524,7 +518,7 @@ pub impl Datum { } return match self.mode { - ByRef => glue::drop_ty(bcx, self.val, self.ty), + ByRef(_) => glue::drop_ty(bcx, self.val, self.ty), ByValue => glue::drop_ty_immediate(bcx, self.val, self.ty) }; } @@ -546,7 +540,7 @@ pub impl Datum { let ptr = self.to_value_llval(bcx); let body = opaque_box_body(bcx, content_ty, ptr); - Datum {val: body, ty: content_ty, mode: ByRef, source: ZeroMem} + Datum {val: body, ty: content_ty, mode: ByRef(ZeroMem)} } fn to_rptr(&self, bcx: block) -> Datum { @@ -561,8 +555,7 @@ pub impl Datum { let llval = self.to_ref_llval(bcx); let rptr_ty = ty::mk_imm_rptr(bcx.tcx(), ty::re_static, self.ty); - Datum {val: llval, ty: rptr_ty, - mode: ByValue, source: RevokeClean} + Datum {val: llval, ty: rptr_ty, mode: ByValue} } fn try_deref(&self, @@ -606,7 +599,7 @@ pub impl Datum { let repr = adt::represent_type(ccx, self.ty); let ty = ty::subst(ccx.tcx, substs, variants[0].args[0]); return match self.mode { - ByRef => { + ByRef(_) => { // Recast lv.val as a pointer to the newtype // rather than a ptr to the enum type. ( @@ -614,8 +607,7 @@ pub impl Datum { val: adt::trans_field_ptr(bcx, repr, self.val, 0, 0), ty: ty, - mode: ByRef, - source: ZeroMem + mode: ByRef(ZeroMem) }), bcx ) @@ -645,7 +637,7 @@ pub impl Datum { let repr = adt::represent_type(ccx, self.ty); let ty = fields[0].mt.ty; return match self.mode { - ByRef => { + ByRef(_) => { // Recast lv.val as a pointer to the newtype rather // than a pointer to the struct type. // FIXME #6572: This isn't correct for structs with @@ -655,8 +647,7 @@ pub impl Datum { val: adt::trans_field_ptr(bcx, repr, self.val, 0, 0), ty: ty, - mode: ByRef, - source: ZeroMem + mode: ByRef(ZeroMem) }), bcx ) @@ -683,8 +674,7 @@ pub impl Datum { Datum { val: lv.to_value_llval(bcx), ty: ty, - mode: ByRef, - source: ZeroMem // *p is an lvalue + mode: ByRef(ZeroMem) } } } diff --git a/src/librustc/middle/trans/expr.rs b/src/librustc/middle/trans/expr.rs index 99860e60c6b..a7d064dde46 100644 --- a/src/librustc/middle/trans/expr.rs +++ b/src/librustc/middle/trans/expr.rs @@ -247,7 +247,7 @@ pub fn trans_to_datum(bcx: block, expr: @ast::expr) -> DatumBlock { // must patchup the type. DatumBlock {bcx: bcx, datum: Datum {val: datum.val, ty: adjusted_ty, - mode: datum.mode, source: datum.source}} + mode: datum.mode}} } fn auto_slice(bcx: block, @@ -793,8 +793,7 @@ fn trans_def_datum_unadjusted(bcx: block, bcx: bcx, datum: Datum {val: llval, ty: rust_ty, - mode: ByValue, - source: RevokeClean} + mode: ByValue} }; } } @@ -920,8 +919,7 @@ fn trans_lvalue_unadjusted(bcx: block, expr: @ast::expr) -> DatumBlock { bcx: bcx, datum: Datum {val: elt, ty: vt.unit_ty, - mode: ByRef, - source: ZeroMem} + mode: ByRef(ZeroMem)} }; } @@ -988,8 +986,7 @@ fn trans_lvalue_unadjusted(bcx: block, expr: @ast::expr) -> DatumBlock { bcx: bcx, datum: Datum {val: val, ty: const_ty, - mode: ByRef, - source: ZeroMem} + mode: ByRef(ZeroMem)} } } _ => { @@ -1014,8 +1011,7 @@ pub fn trans_local_var(bcx: block, def: ast::def) -> Datum { Datum { val: val, ty: local_ty, - mode: ByRef, - source: ZeroMem + mode: ByRef(ZeroMem) } } None => { @@ -1052,8 +1048,7 @@ pub fn trans_local_var(bcx: block, def: ast::def) -> Datum { Datum { val: casted_val, ty: self_info.t, - mode: ByRef, - source: ZeroMem + mode: ByRef(ZeroMem) } } _ => { @@ -1066,7 +1061,7 @@ pub fn trans_local_var(bcx: block, def: ast::def) -> Datum { table: &HashMap, nid: ast::node_id) -> Datum { let (v, mode) = match table.find(&nid) { - Some(&local_mem(v)) => (v, ByRef), + Some(&local_mem(v)) => (v, ByRef(ZeroMem)), Some(&local_imm(v)) => (v, ByValue), None => { bcx.sess().bug(fmt!( @@ -1082,7 +1077,6 @@ pub fn trans_local_var(bcx: block, def: ast::def) -> Datum { val: v, ty: ty, mode: mode, - source: ZeroMem } } } diff --git a/src/librustc/middle/trans/foreign.rs b/src/librustc/middle/trans/foreign.rs index a7a8cd088d2..ae68a28de97 100644 --- a/src/librustc/middle/trans/foreign.rs +++ b/src/librustc/middle/trans/foreign.rs @@ -692,19 +692,15 @@ pub fn trans_intrinsic(ccx: @CrateContext, fcx.llretptr.get()); } ~"move_val" => { - // Create a datum reflecting the value being moved: - // - // - the datum will be by ref if the value is non-immediate; - // - // - the datum has a RevokeClean source because, that way, - // the `move_to()` method does not feel compelled to - // zero out the memory where the datum resides. Zeroing - // is not necessary since, for intrinsics, there is no - // cleanup to concern ourselves with. + // Create a datum reflecting the value being moved. + // Use `appropriate_mode` so that the datum is by ref + // if the value is non-immediate. Note that, with + // intrinsics, there are no argument cleanups to + // concern ourselves with. let tp_ty = substs.tys[0]; let mode = appropriate_mode(tp_ty); let src = Datum {val: get_param(decl, first_real_arg + 1u), - ty: tp_ty, mode: mode, source: RevokeClean}; + ty: tp_ty, mode: mode}; bcx = src.move_to(bcx, DROP_EXISTING, get_param(decl, first_real_arg)); } @@ -713,7 +709,7 @@ pub fn trans_intrinsic(ccx: @CrateContext, let tp_ty = substs.tys[0]; let mode = appropriate_mode(tp_ty); let src = Datum {val: get_param(decl, first_real_arg + 1u), - ty: tp_ty, mode: mode, source: RevokeClean}; + ty: tp_ty, mode: mode}; bcx = src.move_to(bcx, INIT, get_param(decl, first_real_arg)); } ~"min_align_of" => { @@ -832,7 +828,7 @@ pub fn trans_intrinsic(ccx: @CrateContext, } }); let datum = Datum {val: get_param(decl, first_real_arg), - mode: ByRef, ty: fty, source: ZeroMem}; + mode: ByRef(ZeroMem), ty: fty}; let arg_vals = ~[frameaddress_val]; bcx = trans_call_inner( bcx, None, fty, ty::mk_nil(), diff --git a/src/librustc/middle/trans/meth.rs b/src/librustc/middle/trans/meth.rs index 1e43a3c502b..023d931a60b 100644 --- a/src/librustc/middle/trans/meth.rs +++ b/src/librustc/middle/trans/meth.rs @@ -197,7 +197,7 @@ pub fn trans_method_callee(bcx: block, // Replace method_self with method_static here. let mut origin = mentry.origin; match origin { - typeck::method_self(copy trait_id, copy method_index) => { + typeck::method_self(trait_id, method_index) => { // Get the ID of the impl we're inside. let impl_def_id = bcx.fcx.impl_id.get(); @@ -445,7 +445,7 @@ pub fn method_ty_param_count(ccx: @CrateContext, m_id: ast::def_id, _, _)) => { m.generics.ty_params.len() } - copy e => fail!("method_ty_param_count %?", e) + ref e => fail!("method_ty_param_count %?", *e) } } else { csearch::get_type_param_count(ccx.sess.cstore, m_id) -