auto merge of #11387 : pcwalton/rust/de-at-block, r=alexcrichton

r? @brson
This commit is contained in:
bors 2014-01-09 02:26:26 -08:00
commit c34fc5e33b
20 changed files with 1124 additions and 741 deletions

View File

@ -306,12 +306,13 @@ fn opt_eq(tcx: ty::ctxt, a: &Opt, b: &Opt) -> bool {
} }
} }
pub enum opt_result { pub enum opt_result<'a> {
single_result(Result), single_result(Result<'a>),
lower_bound(Result), lower_bound(Result<'a>),
range_result(Result, Result), range_result(Result<'a>, Result<'a>),
} }
fn trans_opt(bcx: @Block, o: &Opt) -> opt_result {
fn trans_opt<'a>(bcx: &'a Block<'a>, o: &Opt) -> opt_result<'a> {
let _icx = push_ctxt("match::trans_opt"); let _icx = push_ctxt("match::trans_opt");
let ccx = bcx.ccx(); let ccx = bcx.ccx();
let bcx = bcx; let bcx = bcx;
@ -346,8 +347,7 @@ fn trans_opt(bcx: @Block, o: &Opt) -> opt_result {
} }
} }
fn variant_opt(bcx: @Block, pat_id: ast::NodeId) fn variant_opt(bcx: &Block, pat_id: ast::NodeId) -> Opt {
-> Opt {
let ccx = bcx.ccx(); let ccx = bcx.ccx();
let def_map = ccx.tcx.def_map.borrow(); let def_map = ccx.tcx.def_map.borrow();
match def_map.get().get_copy(&pat_id) { match def_map.get().get_copy(&pat_id) {
@ -397,8 +397,8 @@ struct BindingInfo {
type BindingsMap = HashMap<Ident, BindingInfo>; type BindingsMap = HashMap<Ident, BindingInfo>;
#[deriving(Clone)] #[deriving(Clone)]
struct ArmData<'a> { struct ArmData<'a,'b> {
bodycx: @Block, bodycx: &'b Block<'b>,
arm: &'a ast::Arm, arm: &'a ast::Arm,
bindings_map: @BindingsMap bindings_map: @BindingsMap
} }
@ -410,13 +410,13 @@ struct ArmData<'a> {
* these pointers are stored in llmatch variables just before executing `data` arm. * these pointers are stored in llmatch variables just before executing `data` arm.
*/ */
#[deriving(Clone)] #[deriving(Clone)]
struct Match<'a> { struct Match<'a,'b> {
pats: ~[@ast::Pat], pats: ~[@ast::Pat],
data: ArmData<'a>, data: ArmData<'a,'b>,
bound_ptrs: ~[(Ident, ValueRef)] bound_ptrs: ~[(Ident, ValueRef)]
} }
impl<'a> Repr for Match<'a> { impl<'a,'b> Repr for Match<'a,'b> {
fn repr(&self, tcx: ty::ctxt) -> ~str { fn repr(&self, tcx: ty::ctxt) -> ~str {
if tcx.sess.verbose() { if tcx.sess.verbose() {
// for many programs, this just take too long to serialize // for many programs, this just take too long to serialize
@ -437,11 +437,12 @@ fn has_nested_bindings(m: &[Match], col: uint) -> bool {
return false; return false;
} }
fn expand_nested_bindings<'r>(bcx: @Block, fn expand_nested_bindings<'r,'b>(
m: &[Match<'r>], bcx: &'b Block<'b>,
m: &[Match<'r,'b>],
col: uint, col: uint,
val: ValueRef) val: ValueRef)
-> ~[Match<'r>] { -> ~[Match<'r,'b>] {
debug!("expand_nested_bindings(bcx={}, m={}, col={}, val={})", debug!("expand_nested_bindings(bcx={}, m={}, col={}, val={})",
bcx.to_str(), bcx.to_str(),
m.repr(bcx.tcx()), m.repr(bcx.tcx()),
@ -471,7 +472,7 @@ fn expand_nested_bindings<'r>(bcx: @Block,
}) })
} }
fn assert_is_binding_or_wild(bcx: @Block, p: @ast::Pat) { fn assert_is_binding_or_wild(bcx: &Block, p: @ast::Pat) {
if !pat_is_binding_or_wild(bcx.tcx().def_map, p) { if !pat_is_binding_or_wild(bcx.tcx().def_map, p) {
bcx.sess().span_bug( bcx.sess().span_bug(
p.span, p.span,
@ -482,13 +483,14 @@ fn assert_is_binding_or_wild(bcx: @Block, p: @ast::Pat) {
type enter_pat<'a> = 'a |@ast::Pat| -> Option<~[@ast::Pat]>; type enter_pat<'a> = 'a |@ast::Pat| -> Option<~[@ast::Pat]>;
fn enter_match<'r>(bcx: @Block, fn enter_match<'r,'b>(
bcx: &'b Block<'b>,
dm: DefMap, dm: DefMap,
m: &[Match<'r>], m: &[Match<'r,'b>],
col: uint, col: uint,
val: ValueRef, val: ValueRef,
e: enter_pat) e: enter_pat)
-> ~[Match<'r>] { -> ~[Match<'r,'b>] {
debug!("enter_match(bcx={}, m={}, col={}, val={})", debug!("enter_match(bcx={}, m={}, col={}, val={})",
bcx.to_str(), bcx.to_str(),
m.repr(bcx.tcx()), m.repr(bcx.tcx()),
@ -531,13 +533,14 @@ fn enter_match<'r>(bcx: @Block,
return result; return result;
} }
fn enter_default<'r>(bcx: @Block, fn enter_default<'r,'b>(
bcx: &'b Block<'b>,
dm: DefMap, dm: DefMap,
m: &[Match<'r>], m: &[Match<'r,'b>],
col: uint, col: uint,
val: ValueRef, val: ValueRef,
chk: FailureHandler) chk: &FailureHandler)
-> ~[Match<'r>] { -> ~[Match<'r,'b>] {
debug!("enter_default(bcx={}, m={}, col={}, val={})", debug!("enter_default(bcx={}, m={}, col={}, val={})",
bcx.to_str(), bcx.to_str(),
m.repr(bcx.tcx()), m.repr(bcx.tcx()),
@ -601,13 +604,14 @@ fn enter_default<'r>(bcx: @Block,
// <nmatsakis> so all patterns must either be records (resp. tuples) or // <nmatsakis> so all patterns must either be records (resp. tuples) or
// wildcards // wildcards
fn enter_opt<'r>(bcx: @Block, fn enter_opt<'r,'b>(
m: &[Match<'r>], bcx: &'b Block<'b>,
m: &[Match<'r,'b>],
opt: &Opt, opt: &Opt,
col: uint, col: uint,
variant_size: uint, variant_size: uint,
val: ValueRef) val: ValueRef)
-> ~[Match<'r>] { -> ~[Match<'r,'b>] {
debug!("enter_opt(bcx={}, m={}, opt={:?}, col={}, val={})", debug!("enter_opt(bcx={}, m={}, opt={:?}, col={}, val={})",
bcx.to_str(), bcx.to_str(),
m.repr(bcx.tcx()), m.repr(bcx.tcx()),
@ -744,13 +748,14 @@ fn enter_opt<'r>(bcx: @Block,
}) })
} }
fn enter_rec_or_struct<'r>(bcx: @Block, fn enter_rec_or_struct<'r,'b>(
bcx: &'b Block<'b>,
dm: DefMap, dm: DefMap,
m: &[Match<'r>], m: &[Match<'r,'b>],
col: uint, col: uint,
fields: &[ast::Ident], fields: &[ast::Ident],
val: ValueRef) val: ValueRef)
-> ~[Match<'r>] { -> ~[Match<'r,'b>] {
debug!("enter_rec_or_struct(bcx={}, m={}, col={}, val={})", debug!("enter_rec_or_struct(bcx={}, m={}, col={}, val={})",
bcx.to_str(), bcx.to_str(),
m.repr(bcx.tcx()), m.repr(bcx.tcx()),
@ -779,13 +784,14 @@ fn enter_rec_or_struct<'r>(bcx: @Block,
}) })
} }
fn enter_tup<'r>(bcx: @Block, fn enter_tup<'r,'b>(
bcx: &'b Block<'b>,
dm: DefMap, dm: DefMap,
m: &[Match<'r>], m: &[Match<'r,'b>],
col: uint, col: uint,
val: ValueRef, val: ValueRef,
n_elts: uint) n_elts: uint)
-> ~[Match<'r>] { -> ~[Match<'r,'b>] {
debug!("enter_tup(bcx={}, m={}, col={}, val={})", debug!("enter_tup(bcx={}, m={}, col={}, val={})",
bcx.to_str(), bcx.to_str(),
m.repr(bcx.tcx()), m.repr(bcx.tcx()),
@ -805,13 +811,14 @@ fn enter_tup<'r>(bcx: @Block,
}) })
} }
fn enter_tuple_struct<'r>(bcx: @Block, fn enter_tuple_struct<'r,'b>(
bcx: &'b Block<'b>,
dm: DefMap, dm: DefMap,
m: &[Match<'r>], m: &[Match<'r,'b>],
col: uint, col: uint,
val: ValueRef, val: ValueRef,
n_elts: uint) n_elts: uint)
-> ~[Match<'r>] { -> ~[Match<'r,'b>] {
debug!("enter_tuple_struct(bcx={}, m={}, col={}, val={})", debug!("enter_tuple_struct(bcx={}, m={}, col={}, val={})",
bcx.to_str(), bcx.to_str(),
m.repr(bcx.tcx()), m.repr(bcx.tcx()),
@ -831,12 +838,13 @@ fn enter_tuple_struct<'r>(bcx: @Block,
}) })
} }
fn enter_box<'r>(bcx: @Block, fn enter_box<'r,'b>(
bcx: &'b Block<'b>,
dm: DefMap, dm: DefMap,
m: &[Match<'r>], m: &[Match<'r,'b>],
col: uint, col: uint,
val: ValueRef) val: ValueRef)
-> ~[Match<'r>] { -> ~[Match<'r,'b>] {
debug!("enter_box(bcx={}, m={}, col={}, val={})", debug!("enter_box(bcx={}, m={}, col={}, val={})",
bcx.to_str(), bcx.to_str(),
m.repr(bcx.tcx()), m.repr(bcx.tcx()),
@ -858,12 +866,13 @@ fn enter_box<'r>(bcx: @Block,
}) })
} }
fn enter_uniq<'r>(bcx: @Block, fn enter_uniq<'r,'b>(
bcx: &'b Block<'b>,
dm: DefMap, dm: DefMap,
m: &[Match<'r>], m: &[Match<'r,'b>],
col: uint, col: uint,
val: ValueRef) val: ValueRef)
-> ~[Match<'r>] { -> ~[Match<'r,'b>] {
debug!("enter_uniq(bcx={}, m={}, col={}, val={})", debug!("enter_uniq(bcx={}, m={}, col={}, val={})",
bcx.to_str(), bcx.to_str(),
m.repr(bcx.tcx()), m.repr(bcx.tcx()),
@ -885,12 +894,14 @@ fn enter_uniq<'r>(bcx: @Block,
}) })
} }
fn enter_region<'r>(bcx: @Block, fn enter_region<'r,
'b>(
bcx: &'b Block<'b>,
dm: DefMap, dm: DefMap,
m: &[Match<'r>], m: &[Match<'r,'b>],
col: uint, col: uint,
val: ValueRef) val: ValueRef)
-> ~[Match<'r>] { -> ~[Match<'r,'b>] {
debug!("enter_region(bcx={}, m={}, col={}, val={})", debug!("enter_region(bcx={}, m={}, col={}, val={})",
bcx.to_str(), bcx.to_str(),
m.repr(bcx.tcx()), m.repr(bcx.tcx()),
@ -915,7 +926,7 @@ fn enter_region<'r>(bcx: @Block,
// Returns the options in one column of matches. An option is something that // Returns the options in one column of matches. An option is something that
// needs to be conditionally matched at runtime; for example, the discriminant // needs to be conditionally matched at runtime; for example, the discriminant
// on a set of enum variants or a literal. // on a set of enum variants or a literal.
fn get_options(bcx: @Block, m: &[Match], col: uint) -> ~[Opt] { fn get_options(bcx: &Block, m: &[Match], col: uint) -> ~[Opt] {
let ccx = bcx.ccx(); let ccx = bcx.ccx();
fn add_to_set(tcx: ty::ctxt, set: &mut ~[Opt], val: Opt) { fn add_to_set(tcx: ty::ctxt, set: &mut ~[Opt], val: Opt) {
if set.iter().any(|l| opt_eq(tcx, l, &val)) {return;} if set.iter().any(|l| opt_eq(tcx, l, &val)) {return;}
@ -1005,16 +1016,17 @@ fn get_options(bcx: @Block, m: &[Match], col: uint) -> ~[Opt] {
return found; return found;
} }
struct ExtractedBlock { struct ExtractedBlock<'a> {
vals: ~[ValueRef], vals: ~[ValueRef],
bcx: @Block bcx: &'a Block<'a>,
} }
fn extract_variant_args(bcx: @Block, fn extract_variant_args<'a>(
bcx: &'a Block<'a>,
repr: &adt::Repr, repr: &adt::Repr,
disr_val: ty::Disr, disr_val: ty::Disr,
val: ValueRef) val: ValueRef)
-> ExtractedBlock { -> ExtractedBlock<'a> {
let _icx = push_ctxt("match::extract_variant_args"); let _icx = push_ctxt("match::extract_variant_args");
let args = vec::from_fn(adt::num_args(repr, disr_val), |i| { let args = vec::from_fn(adt::num_args(repr, disr_val), |i| {
adt::trans_field_ptr(bcx, repr, val, disr_val, i) adt::trans_field_ptr(bcx, repr, val, disr_val, i)
@ -1023,7 +1035,8 @@ fn extract_variant_args(bcx: @Block,
ExtractedBlock { vals: args, bcx: bcx } ExtractedBlock { vals: args, bcx: bcx }
} }
fn match_datum(bcx: @Block, val: ValueRef, pat_id: ast::NodeId) -> Datum { fn match_datum<'a>(bcx: &'a Block<'a>, val: ValueRef, pat_id: ast::NodeId)
-> Datum {
//! Helper for converting from the ValueRef that we pass around in //! Helper for converting from the ValueRef that we pass around in
//! the match code, which is always by ref, into a Datum. Eventually //! the match code, which is always by ref, into a Datum. Eventually
//! we should just pass around a Datum and be done with it. //! we should just pass around a Datum and be done with it.
@ -1033,14 +1046,15 @@ fn match_datum(bcx: @Block, val: ValueRef, pat_id: ast::NodeId) -> Datum {
} }
fn extract_vec_elems(bcx: @Block, fn extract_vec_elems<'a>(
bcx: &'a Block<'a>,
pat_span: Span, pat_span: Span,
pat_id: ast::NodeId, pat_id: ast::NodeId,
elem_count: uint, elem_count: uint,
slice: Option<uint>, slice: Option<uint>,
val: ValueRef, val: ValueRef,
count: ValueRef) count: ValueRef)
-> ExtractedBlock { -> ExtractedBlock<'a> {
let _icx = push_ctxt("match::extract_vec_elems"); let _icx = push_ctxt("match::extract_vec_elems");
let vec_datum = match_datum(bcx, val, pat_id); let vec_datum = match_datum(bcx, val, pat_id);
let (bcx, base, len) = vec_datum.get_vec_base_and_len(bcx, pat_span, pat_id, 0); let (bcx, base, len) = vec_datum.get_vec_base_and_len(bcx, pat_span, pat_id, 0);
@ -1086,7 +1100,8 @@ fn extract_vec_elems(bcx: @Block,
/// Function returns None if there is no struct pattern. /// Function returns None if there is no struct pattern.
/// Function doesn't collect fields from struct-like enum variants. /// Function doesn't collect fields from struct-like enum variants.
/// Function can return empty list if there is only wildcard struct pattern. /// Function can return empty list if there is only wildcard struct pattern.
fn collect_record_or_struct_fields(bcx: @Block, fn collect_record_or_struct_fields<'a>(
bcx: &'a Block<'a>,
m: &[Match], m: &[Match],
col: uint) col: uint)
-> Option<~[ast::Ident]> { -> Option<~[ast::Ident]> {
@ -1122,10 +1137,7 @@ fn collect_record_or_struct_fields(bcx: @Block,
} }
} }
fn pats_require_rooting(bcx: @Block, fn pats_require_rooting(bcx: &Block, m: &[Match], col: uint) -> bool {
m: &[Match],
col: uint)
-> bool {
m.iter().any(|br| { m.iter().any(|br| {
let pat_id = br.pats[col].id; let pat_id = br.pats[col].id;
let key = root_map_key {id: pat_id, derefs: 0u }; let key = root_map_key {id: pat_id, derefs: 0u };
@ -1134,11 +1146,12 @@ fn pats_require_rooting(bcx: @Block,
}) })
} }
fn root_pats_as_necessary(mut bcx: @Block, fn root_pats_as_necessary<'r,'b>(
m: &[Match], mut bcx: &'b Block<'b>,
m: &[Match<'r,'b>],
col: uint, col: uint,
val: ValueRef) val: ValueRef)
-> @Block { -> &'b Block<'b> {
for br in m.iter() { for br in m.iter() {
let pat_id = br.pats[col].id; let pat_id = br.pats[col].id;
if pat_id != 0 { if pat_id != 0 {
@ -1181,7 +1194,7 @@ fn any_tup_pat(m: &[Match], col: uint) -> bool {
any_pat!(m, ast::PatTup(_)) any_pat!(m, ast::PatTup(_))
} }
fn any_tuple_struct_pat(bcx: @Block, m: &[Match], col: uint) -> bool { fn any_tuple_struct_pat(bcx: &Block, m: &[Match], col: uint) -> bool {
m.iter().any(|br| { m.iter().any(|br| {
let pat = br.pats[col]; let pat = br.pats[col];
match pat.node { match pat.node {
@ -1198,18 +1211,14 @@ fn any_tuple_struct_pat(bcx: @Block, m: &[Match], col: uint) -> bool {
}) })
} }
trait CustomFailureHandler { struct DynamicFailureHandler<'a> {
fn handle_fail(&self) -> BasicBlockRef; bcx: &'a Block<'a>,
}
struct DynamicFailureHandler {
bcx: @Block,
sp: Span, sp: Span,
msg: @str, msg: @str,
finished: @Cell<Option<BasicBlockRef>>, finished: @Cell<Option<BasicBlockRef>>,
} }
impl CustomFailureHandler for DynamicFailureHandler { impl<'a> DynamicFailureHandler<'a> {
fn handle_fail(&self) -> BasicBlockRef { fn handle_fail(&self) -> BasicBlockRef {
match self.finished.get() { match self.finished.get() {
Some(bb) => return bb, Some(bb) => return bb,
@ -1224,13 +1233,13 @@ impl CustomFailureHandler for DynamicFailureHandler {
} }
/// What to do when the pattern match fails. /// What to do when the pattern match fails.
enum FailureHandler { enum FailureHandler<'a> {
Infallible, Infallible,
JumpToBasicBlock(BasicBlockRef), JumpToBasicBlock(BasicBlockRef),
CustomFailureHandlerClass(@CustomFailureHandler), DynamicFailureHandlerClass(~DynamicFailureHandler<'a>),
} }
impl FailureHandler { impl<'a> FailureHandler<'a> {
fn is_infallible(&self) -> bool { fn is_infallible(&self) -> bool {
match *self { match *self {
Infallible => true, Infallible => true,
@ -1248,8 +1257,8 @@ impl FailureHandler {
fail!("attempted to fail in infallible failure handler!") fail!("attempted to fail in infallible failure handler!")
} }
JumpToBasicBlock(basic_block) => basic_block, JumpToBasicBlock(basic_block) => basic_block,
CustomFailureHandlerClass(custom_failure_handler) => { DynamicFailureHandlerClass(ref dynamic_failure_handler) => {
custom_failure_handler.handle_fail() dynamic_failure_handler.handle_fail()
} }
} }
} }
@ -1290,11 +1299,12 @@ pub enum branch_kind { no_branch, single, switch, compare, compare_vec_len, }
// Compiles a comparison between two things. // Compiles a comparison between two things.
// //
// NB: This must produce an i1, not a Rust bool (i8). // NB: This must produce an i1, not a Rust bool (i8).
fn compare_values(cx: @Block, fn compare_values<'a>(
cx: &'a Block<'a>,
lhs: ValueRef, lhs: ValueRef,
rhs: ValueRef, rhs: ValueRef,
rhs_t: ty::t) rhs_t: ty::t)
-> Result { -> Result<'a> {
let _icx = push_ctxt("compare_values"); let _icx = push_ctxt("compare_values");
if ty::type_is_scalar(rhs_t) { if ty::type_is_scalar(rhs_t) {
let rs = compare_scalar_types(cx, lhs, rhs, rhs_t, ast::BiEq); let rs = compare_scalar_types(cx, lhs, rhs, rhs_t, ast::BiEq);
@ -1333,11 +1343,11 @@ fn compare_values(cx: @Block,
} }
} }
fn store_non_ref_bindings(bcx: @Block, fn store_non_ref_bindings<'a>(
bcx: &'a Block<'a>,
bindings_map: &BindingsMap, bindings_map: &BindingsMap,
mut opt_temp_cleanups: Option<&mut ~[ValueRef]>) mut opt_temp_cleanups: Option<&mut ~[ValueRef]>)
-> @Block -> &'a Block<'a> {
{
/*! /*!
* *
* For each copy/move binding, copy the value from the value * For each copy/move binding, copy the value from the value
@ -1367,9 +1377,11 @@ fn store_non_ref_bindings(bcx: @Block,
return bcx; return bcx;
} }
fn insert_lllocals(bcx: @Block, fn insert_lllocals<'a>(
bcx: &'a Block<'a>,
bindings_map: &BindingsMap, bindings_map: &BindingsMap,
add_cleans: bool) -> @Block { add_cleans: bool)
-> &'a Block<'a> {
/*! /*!
* For each binding in `data.bindings_map`, adds an appropriate entry into * For each binding in `data.bindings_map`, adds an appropriate entry into
* the `fcx.lllocals` map. If add_cleans is true, then adds cleanups for * the `fcx.lllocals` map. If add_cleans is true, then adds cleanups for
@ -1413,13 +1425,15 @@ fn insert_lllocals(bcx: @Block,
return bcx; return bcx;
} }
fn compile_guard(bcx: @Block, fn compile_guard<'r,
'b>(
bcx: &'b Block<'b>,
guard_expr: &ast::Expr, guard_expr: &ast::Expr,
data: &ArmData, data: &ArmData,
m: &[Match], m: &[Match<'r,'b>],
vals: &[ValueRef], vals: &[ValueRef],
chk: FailureHandler) chk: &FailureHandler)
-> @Block { -> &'b Block<'b> {
debug!("compile_guard(bcx={}, guard_expr={}, m={}, vals={})", debug!("compile_guard(bcx={}, guard_expr={}, m={}, vals={})",
bcx.to_str(), bcx.to_str(),
bcx.expr_to_str(guard_expr), bcx.expr_to_str(guard_expr),
@ -1454,7 +1468,8 @@ fn compile_guard(bcx: @Block,
bcx bcx
}); });
fn drop_bindings(bcx: @Block, data: &ArmData) -> @Block { fn drop_bindings<'a>(bcx: &'a Block<'a>, data: &ArmData)
-> &'a Block<'a> {
let mut bcx = bcx; let mut bcx = bcx;
for (_, &binding_info) in data.bindings_map.iter() { for (_, &binding_info) in data.bindings_map.iter() {
match binding_info.trmode { match binding_info.trmode {
@ -1470,10 +1485,12 @@ fn compile_guard(bcx: @Block,
} }
} }
fn compile_submatch(bcx: @Block, fn compile_submatch<'r,
m: &[Match], 'b>(
bcx: &'b Block<'b>,
m: &[Match<'r,'b>],
vals: &[ValueRef], vals: &[ValueRef],
chk: FailureHandler) { chk: &FailureHandler) {
debug!("compile_submatch(bcx={}, m={}, vals={})", debug!("compile_submatch(bcx={}, m={}, vals={})",
bcx.to_str(), bcx.to_str(),
m.repr(bcx.tcx()), m.repr(bcx.tcx()),
@ -1522,10 +1539,12 @@ fn compile_submatch(bcx: @Block,
} }
} }
fn compile_submatch_continue(mut bcx: @Block, fn compile_submatch_continue<'r,
m: &[Match], 'b>(
mut bcx: &'b Block<'b>,
m: &[Match<'r,'b>],
vals: &[ValueRef], vals: &[ValueRef],
chk: FailureHandler, chk: &FailureHandler,
col: uint, col: uint,
val: ValueRef) { val: ValueRef) {
let tcx = bcx.tcx(); let tcx = bcx.tcx();
@ -1695,7 +1714,7 @@ fn compile_submatch_continue(mut bcx: @Block,
// the failure case so that instead of failing, it proceeds to // the failure case so that instead of failing, it proceeds to
// try more matching. branch_chk, then, is the proper failure case // try more matching. branch_chk, then, is the proper failure case
// for the current conditional branch. // for the current conditional branch.
let mut branch_chk = chk; let mut branch_chk = None;
let mut opt_cx = else_cx; let mut opt_cx = else_cx;
if !exhaustive || i+1 < len { if !exhaustive || i+1 < len {
opt_cx = sub_block(bcx, "match_case"); opt_cx = sub_block(bcx, "match_case");
@ -1791,7 +1810,7 @@ fn compile_submatch_continue(mut bcx: @Block,
// If none of these subcases match, move on to the // If none of these subcases match, move on to the
// next condition. // next condition.
branch_chk = JumpToBasicBlock(bcx.llbb); branch_chk = Some(JumpToBasicBlock(bcx.llbb));
CondBr(after_cx, matches, opt_cx.llbb, bcx.llbb); CondBr(after_cx, matches, opt_cx.llbb, bcx.llbb);
} }
_ => () _ => ()
@ -1825,7 +1844,13 @@ fn compile_submatch_continue(mut bcx: @Block,
} }
let opt_ms = enter_opt(opt_cx, m, opt, col, size, val); let opt_ms = enter_opt(opt_cx, m, opt, col, size, val);
let opt_vals = vec::append(unpacked, vals_left); let opt_vals = vec::append(unpacked, vals_left);
compile_submatch(opt_cx, opt_ms, opt_vals, branch_chk);
match branch_chk {
None => compile_submatch(opt_cx, opt_ms, opt_vals, chk),
Some(branch_chk) => {
compile_submatch(opt_cx, opt_ms, opt_vals, &branch_chk)
}
}
} }
// Compile the fall-through case, if any // Compile the fall-through case, if any
@ -1839,18 +1864,20 @@ fn compile_submatch_continue(mut bcx: @Block,
} }
} }
pub fn trans_match(bcx: @Block, pub fn trans_match<'a>(
bcx: &'a Block<'a>,
match_expr: &ast::Expr, match_expr: &ast::Expr,
discr_expr: &ast::Expr, discr_expr: &ast::Expr,
arms: &[ast::Arm], arms: &[ast::Arm],
dest: Dest) -> @Block { dest: Dest)
-> &'a Block<'a> {
let _icx = push_ctxt("match::trans_match"); let _icx = push_ctxt("match::trans_match");
with_scope(bcx, match_expr.info(), "match", |bcx| { with_scope(bcx, match_expr.info(), "match", |bcx| {
trans_match_inner(bcx, discr_expr, arms, dest) trans_match_inner(bcx, discr_expr, arms, dest)
}) })
} }
fn create_bindings_map(bcx: @Block, pat: @ast::Pat) -> BindingsMap { fn create_bindings_map(bcx: &Block, pat: @ast::Pat) -> BindingsMap {
// Create the bindings map, which is a mapping from each binding name // Create the bindings map, which is a mapping from each binding name
// to an alloca() that will be the value for that local variable. // to an alloca() that will be the value for that local variable.
// Note that we use the names because each binding will have many ids // Note that we use the names because each binding will have many ids
@ -1890,10 +1917,12 @@ fn create_bindings_map(bcx: @Block, pat: @ast::Pat) -> BindingsMap {
return bindings_map; return bindings_map;
} }
fn trans_match_inner(scope_cx: @Block, fn trans_match_inner<'a>(
scope_cx: &'a Block<'a>,
discr_expr: &ast::Expr, discr_expr: &ast::Expr,
arms: &[ast::Arm], arms: &[ast::Arm],
dest: Dest) -> @Block { dest: Dest)
-> &'a Block<'a> {
let _icx = push_ctxt("match::trans_match_inner"); let _icx = push_ctxt("match::trans_match_inner");
let mut bcx = scope_cx; let mut bcx = scope_cx;
let tcx = bcx.tcx(); let tcx = bcx.tcx();
@ -1930,19 +1959,19 @@ fn trans_match_inner(scope_cx: @Block,
if ty::type_is_empty(tcx, t) { if ty::type_is_empty(tcx, t) {
// Special case for empty types // Special case for empty types
let fail_cx = @Cell::new(None); let fail_cx = @Cell::new(None);
let fail_handler = @DynamicFailureHandler { let fail_handler = ~DynamicFailureHandler {
bcx: scope_cx, bcx: scope_cx,
sp: discr_expr.span, sp: discr_expr.span,
msg: @"scrutinizing value that can't exist", msg: @"scrutinizing value that can't exist",
finished: fail_cx, finished: fail_cx,
} as @CustomFailureHandler; };
CustomFailureHandlerClass(fail_handler) DynamicFailureHandlerClass(fail_handler)
} else { } else {
Infallible Infallible
} }
}; };
let lldiscr = discr_datum.to_ref_llval(bcx); let lldiscr = discr_datum.to_ref_llval(bcx);
compile_submatch(bcx, matches, [lldiscr], chk); compile_submatch(bcx, matches, [lldiscr], &chk);
let mut arm_cxs = ~[]; let mut arm_cxs = ~[];
for arm_data in arm_datas.iter() { for arm_data in arm_datas.iter() {
@ -1975,10 +2004,11 @@ enum IrrefutablePatternBindingMode {
BindArgument BindArgument
} }
pub fn store_local(bcx: @Block, pub fn store_local<'a>(
bcx: &'a Block<'a>,
pat: @ast::Pat, pat: @ast::Pat,
opt_init_expr: Option<@ast::Expr>) opt_init_expr: Option<@ast::Expr>)
-> @Block { -> &'a Block<'a> {
/*! /*!
* Generates code for a local variable declaration like * Generates code for a local variable declaration like
* `let <pat>;` or `let <pat> = <opt_init_expr>`. * `let <pat>;` or `let <pat> = <opt_init_expr>`.
@ -2029,7 +2059,8 @@ pub fn store_local(bcx: @Block,
} }
}; };
fn create_dummy_locals(mut bcx: @Block, pat: @ast::Pat) -> @Block { fn create_dummy_locals<'a>(mut bcx: &'a Block<'a>, pat: @ast::Pat)
-> &'a Block<'a> {
// create dummy memory for the variables if we have no // create dummy memory for the variables if we have no
// value to store into them immediately // value to store into them immediately
let tcx = bcx.tcx(); let tcx = bcx.tcx();
@ -2042,10 +2073,8 @@ pub fn store_local(bcx: @Block,
} }
} }
pub fn store_arg(mut bcx: @Block, pub fn store_arg<'a>(mut bcx: &'a Block<'a>, pat: @ast::Pat, llval: ValueRef)
pat: @ast::Pat, -> &'a Block<'a> {
llval: ValueRef)
-> @Block {
/*! /*!
* Generates code for argument patterns like `fn foo(<pat>: T)`. * Generates code for argument patterns like `fn foo(<pat>: T)`.
* Creates entries in the `llargs` map for each of the bindings * Creates entries in the `llargs` map for each of the bindings
@ -2090,12 +2119,16 @@ pub fn store_arg(mut bcx: @Block,
return bcx; return bcx;
} }
fn mk_binding_alloca(mut bcx: @Block, fn mk_binding_alloca<'a>(
mut bcx: &'a Block<'a>,
p_id: ast::NodeId, p_id: ast::NodeId,
path: &ast::Path, path: &ast::Path,
binding_mode: IrrefutablePatternBindingMode, binding_mode: IrrefutablePatternBindingMode,
populate: |@Block, ty::t, ValueRef| -> @Block) populate: |&'a Block<'a>,
-> @Block { ty::t,
ValueRef|
-> &'a Block<'a>)
-> &'a Block<'a> {
let var_ty = node_id_type(bcx, p_id); let var_ty = node_id_type(bcx, p_id);
let ident = ast_util::path_to_ident(path); let ident = ast_util::path_to_ident(path);
let llval = alloc_ty(bcx, var_ty, bcx.ident(ident)); let llval = alloc_ty(bcx, var_ty, bcx.ident(ident));
@ -2109,11 +2142,12 @@ fn mk_binding_alloca(mut bcx: @Block,
return bcx; return bcx;
} }
fn bind_irrefutable_pat(bcx: @Block, fn bind_irrefutable_pat<'a>(
bcx: &'a Block<'a>,
pat: @ast::Pat, pat: @ast::Pat,
val: ValueRef, val: ValueRef,
binding_mode: IrrefutablePatternBindingMode) binding_mode: IrrefutablePatternBindingMode)
-> @Block { -> &'a Block<'a> {
/*! /*!
* A simple version of the pattern matching code that only handles * A simple version of the pattern matching code that only handles
* irrefutable patterns. This is used in let/argument patterns, * irrefutable patterns. This is used in let/argument patterns,

View File

@ -111,7 +111,7 @@ pub struct Struct {
* these, for places in trans where the `ty::t` isn't directly * these, for places in trans where the `ty::t` isn't directly
* available. * available.
*/ */
pub fn represent_node(bcx: @Block, node: ast::NodeId) -> @Repr { pub fn represent_node(bcx: &Block, node: ast::NodeId) -> @Repr {
represent_type(bcx.ccx(), node_id_type(bcx, node)) represent_type(bcx.ccx(), node_id_type(bcx, node))
} }
@ -463,7 +463,7 @@ fn struct_llfields(cx: &CrateContext, st: &Struct, sizing: bool) -> ~[Type] {
* *
* This should ideally be less tightly tied to `_match`. * This should ideally be less tightly tied to `_match`.
*/ */
pub fn trans_switch(bcx: @Block, r: &Repr, scrutinee: ValueRef) pub fn trans_switch(bcx: &Block, r: &Repr, scrutinee: ValueRef)
-> (_match::branch_kind, Option<ValueRef>) { -> (_match::branch_kind, Option<ValueRef>) {
match *r { match *r {
CEnum(..) | General(..) => { CEnum(..) | General(..) => {
@ -481,7 +481,7 @@ pub fn trans_switch(bcx: @Block, r: &Repr, scrutinee: ValueRef)
/// Obtain the actual discriminant of a value. /// Obtain the actual discriminant of a value.
pub fn trans_get_discr(bcx: @Block, r: &Repr, scrutinee: ValueRef, cast_to: Option<Type>) pub fn trans_get_discr(bcx: &Block, r: &Repr, scrutinee: ValueRef, cast_to: Option<Type>)
-> ValueRef { -> ValueRef {
let signed; let signed;
let val; let val;
@ -510,7 +510,7 @@ pub fn trans_get_discr(bcx: @Block, r: &Repr, scrutinee: ValueRef, cast_to: Opti
} }
} }
fn nullable_bitdiscr(bcx: @Block, nonnull: &Struct, nndiscr: Disr, ptrfield: uint, fn nullable_bitdiscr(bcx: &Block, nonnull: &Struct, nndiscr: Disr, ptrfield: uint,
scrutinee: ValueRef) -> ValueRef { scrutinee: ValueRef) -> ValueRef {
let cmp = if nndiscr == 0 { IntEQ } else { IntNE }; let cmp = if nndiscr == 0 { IntEQ } else { IntNE };
let llptr = Load(bcx, GEPi(bcx, scrutinee, [0, ptrfield])); let llptr = Load(bcx, GEPi(bcx, scrutinee, [0, ptrfield]));
@ -519,7 +519,7 @@ fn nullable_bitdiscr(bcx: @Block, nonnull: &Struct, nndiscr: Disr, ptrfield: uin
} }
/// Helper for cases where the discriminant is simply loaded. /// Helper for cases where the discriminant is simply loaded.
fn load_discr(bcx: @Block, ity: IntType, ptr: ValueRef, min: Disr, max: Disr) fn load_discr(bcx: &Block, ity: IntType, ptr: ValueRef, min: Disr, max: Disr)
-> ValueRef { -> ValueRef {
let llty = ll_inttype(bcx.ccx(), ity); let llty = ll_inttype(bcx.ccx(), ity);
assert_eq!(val_ty(ptr), llty.ptr_to()); assert_eq!(val_ty(ptr), llty.ptr_to());
@ -547,7 +547,8 @@ fn load_discr(bcx: @Block, ity: IntType, ptr: ValueRef, min: Disr, max: Disr)
* *
* This should ideally be less tightly tied to `_match`. * This should ideally be less tightly tied to `_match`.
*/ */
pub fn trans_case(bcx: @Block, r: &Repr, discr: Disr) -> _match::opt_result { pub fn trans_case<'a>(bcx: &'a Block<'a>, r: &Repr, discr: Disr)
-> _match::opt_result<'a> {
match *r { match *r {
CEnum(ity, _, _) => { CEnum(ity, _, _) => {
_match::single_result(rslt(bcx, C_integral(ll_inttype(bcx.ccx(), ity), _match::single_result(rslt(bcx, C_integral(ll_inttype(bcx.ccx(), ity),
@ -572,7 +573,7 @@ pub fn trans_case(bcx: @Block, r: &Repr, discr: Disr) -> _match::opt_result {
* representation. The fields, if any, should then be initialized via * representation. The fields, if any, should then be initialized via
* `trans_field_ptr`. * `trans_field_ptr`.
*/ */
pub fn trans_start_init(bcx: @Block, r: &Repr, val: ValueRef, discr: Disr) { pub fn trans_start_init(bcx: &Block, r: &Repr, val: ValueRef, discr: Disr) {
match *r { match *r {
CEnum(ity, min, max) => { CEnum(ity, min, max) => {
assert_discr_in_range(ity, min, max, discr); assert_discr_in_range(ity, min, max, discr);
@ -628,7 +629,7 @@ pub fn num_args(r: &Repr, discr: Disr) -> uint {
} }
/// Access a field, at a point when the value's case is known. /// Access a field, at a point when the value's case is known.
pub fn trans_field_ptr(bcx: @Block, r: &Repr, val: ValueRef, discr: Disr, pub fn trans_field_ptr(bcx: &Block, r: &Repr, val: ValueRef, discr: Disr,
ix: uint) -> ValueRef { ix: uint) -> ValueRef {
// Note: if this ever needs to generate conditionals (e.g., if we // Note: if this ever needs to generate conditionals (e.g., if we
// decide to do some kind of cdr-coding-like non-unique repr // decide to do some kind of cdr-coding-like non-unique repr
@ -661,7 +662,7 @@ pub fn trans_field_ptr(bcx: @Block, r: &Repr, val: ValueRef, discr: Disr,
} }
} }
fn struct_field_ptr(bcx: @Block, st: &Struct, val: ValueRef, ix: uint, fn struct_field_ptr(bcx: &Block, st: &Struct, val: ValueRef, ix: uint,
needs_cast: bool) -> ValueRef { needs_cast: bool) -> ValueRef {
let ccx = bcx.ccx(); let ccx = bcx.ccx();
@ -677,7 +678,7 @@ fn struct_field_ptr(bcx: @Block, st: &Struct, val: ValueRef, ix: uint,
} }
/// Access the struct drop flag, if present. /// Access the struct drop flag, if present.
pub fn trans_drop_flag_ptr(bcx: @Block, r: &Repr, val: ValueRef) -> ValueRef { pub fn trans_drop_flag_ptr(bcx: &Block, r: &Repr, val: ValueRef) -> ValueRef {
match *r { match *r {
Univariant(ref st, true) => GEPi(bcx, val, [0, st.fields.len() - 1]), Univariant(ref st, true) => GEPi(bcx, val, [0, st.fields.len() - 1]),
_ => bcx.ccx().sess.bug("tried to get drop flag of non-droppable type") _ => bcx.ccx().sess.bug("tried to get drop flag of non-droppable type")

View File

@ -27,8 +27,8 @@ use middle::trans::type_::Type;
use syntax::ast; use syntax::ast;
// Take an inline assembly expression and splat it out via LLVM // Take an inline assembly expression and splat it out via LLVM
pub fn trans_inline_asm(bcx: @Block, ia: &ast::inline_asm) -> @Block { pub fn trans_inline_asm<'a>(bcx: &'a Block<'a>, ia: &ast::inline_asm)
-> &'a Block<'a> {
let mut bcx = bcx; let mut bcx = bcx;
let mut constraints = ~[]; let mut constraints = ~[];
let mut cleanups = ~[]; let mut cleanups = ~[];

View File

@ -68,13 +68,14 @@ use util::ppaux::{Repr, ty_to_str};
use util::sha2::Sha256; use util::sha2::Sha256;
use middle::trans::type_::Type; use middle::trans::type_::Type;
use extra::arena::TypedArena;
use extra::time;
use std::c_str::ToCStr; use std::c_str::ToCStr;
use std::cell::{Cell, RefCell}; use std::cell::{Cell, RefCell};
use std::hashmap::HashMap; use std::hashmap::HashMap;
use std::libc::c_uint; use std::libc::c_uint;
use std::vec; use std::vec;
use std::local_data; use std::local_data;
use extra::time;
use syntax::ast::Name; use syntax::ast::Name;
use syntax::ast_map::{path, path_elt_to_str, path_name, path_pretty_name}; use syntax::ast_map::{path, path_elt_to_str, path_name, path_pretty_name};
use syntax::ast_util::{local_def, is_local}; use syntax::ast_util::{local_def, is_local};
@ -307,9 +308,8 @@ pub fn get_extern_const(externs: &mut ExternMap, llmod: ModuleRef,
// known. // known.
// //
// The runtime equivalent is box_body() in "rust_internal.h". // The runtime equivalent is box_body() in "rust_internal.h".
pub fn opaque_box_body(bcx: @Block, pub fn opaque_box_body(bcx: &Block, body_t: ty::t, boxptr: ValueRef)
body_t: ty::t, -> ValueRef {
boxptr: ValueRef) -> ValueRef {
let _icx = push_ctxt("opaque_box_body"); let _icx = push_ctxt("opaque_box_body");
let ccx = bcx.ccx(); let ccx = bcx.ccx();
let ty = type_of(ccx, body_t); let ty = type_of(ccx, body_t);
@ -320,14 +320,16 @@ pub fn opaque_box_body(bcx: @Block,
// malloc_raw_dyn: allocates a box to contain a given type, but with a // malloc_raw_dyn: allocates a box to contain a given type, but with a
// potentially dynamic size. // potentially dynamic size.
pub fn malloc_raw_dyn(bcx: @Block, pub fn malloc_raw_dyn<'a>(
bcx: &'a Block,
t: ty::t, t: ty::t,
heap: heap, heap: heap,
size: ValueRef) -> Result { size: ValueRef)
-> Result<'a> {
let _icx = push_ctxt("malloc_raw"); let _icx = push_ctxt("malloc_raw");
let ccx = bcx.ccx(); let ccx = bcx.ccx();
fn require_alloc_fn(bcx: @Block, t: ty::t, it: LangItem) -> ast::DefId { fn require_alloc_fn(bcx: &Block, t: ty::t, it: LangItem) -> ast::DefId {
let li = &bcx.tcx().lang_items; let li = &bcx.tcx().lang_items;
match li.require(it) { match li.require(it) {
Ok(id) => id, Ok(id) => id,
@ -387,22 +389,27 @@ pub fn malloc_raw_dyn(bcx: @Block,
// malloc_raw: expects an unboxed type and returns a pointer to // malloc_raw: expects an unboxed type and returns a pointer to
// enough space for a box of that type. This includes a rust_opaque_box // enough space for a box of that type. This includes a rust_opaque_box
// header. // header.
pub fn malloc_raw(bcx: @Block, t: ty::t, heap: heap) -> Result { pub fn malloc_raw<'a>(bcx: &'a Block<'a>, t: ty::t, heap: heap)
-> Result<'a> {
let ty = type_of(bcx.ccx(), t); let ty = type_of(bcx.ccx(), t);
let size = llsize_of(bcx.ccx(), ty); let size = llsize_of(bcx.ccx(), ty);
malloc_raw_dyn(bcx, t, heap, size) malloc_raw_dyn(bcx, t, heap, size)
} }
pub struct MallocResult { pub struct MallocResult<'a> {
bcx: @Block, bcx: &'a Block<'a>,
smart_ptr: ValueRef, smart_ptr: ValueRef,
body: ValueRef body: ValueRef
} }
// malloc_general_dyn: usefully wraps malloc_raw_dyn; allocates a smart // malloc_general_dyn: usefully wraps malloc_raw_dyn; allocates a smart
// pointer, and pulls out the body // pointer, and pulls out the body
pub fn malloc_general_dyn(bcx: @Block, t: ty::t, heap: heap, size: ValueRef) pub fn malloc_general_dyn<'a>(
-> MallocResult { bcx: &'a Block<'a>,
t: ty::t,
heap: heap,
size: ValueRef)
-> MallocResult<'a> {
assert!(heap != heap_exchange); assert!(heap != heap_exchange);
let _icx = push_ctxt("malloc_general"); let _icx = push_ctxt("malloc_general");
let Result {bcx: bcx, val: llbox} = malloc_raw_dyn(bcx, t, heap, size); let Result {bcx: bcx, val: llbox} = malloc_raw_dyn(bcx, t, heap, size);
@ -415,13 +422,14 @@ pub fn malloc_general_dyn(bcx: @Block, t: ty::t, heap: heap, size: ValueRef)
} }
} }
pub fn malloc_general(bcx: @Block, t: ty::t, heap: heap) -> MallocResult { pub fn malloc_general<'a>(bcx: &'a Block, t: ty::t, heap: heap)
-> MallocResult<'a> {
let ty = type_of(bcx.ccx(), t); let ty = type_of(bcx.ccx(), t);
assert!(heap != heap_exchange); assert!(heap != heap_exchange);
malloc_general_dyn(bcx, t, heap, llsize_of(bcx.ccx(), ty)) malloc_general_dyn(bcx, t, heap, llsize_of(bcx.ccx(), ty))
} }
pub fn heap_for_unique(bcx: @Block, t: ty::t) -> heap { pub fn heap_for_unique(bcx: &Block, t: ty::t) -> heap {
if ty::type_contents(bcx.tcx(), t).owns_managed() { if ty::type_contents(bcx.tcx(), t).owns_managed() {
heap_managed_unique heap_managed_unique
} else { } else {
@ -429,7 +437,7 @@ pub fn heap_for_unique(bcx: @Block, t: ty::t) -> heap {
} }
} }
pub fn maybe_set_managed_unique_rc(bcx: @Block, bx: ValueRef, heap: heap) { pub fn maybe_set_managed_unique_rc(bcx: &Block, bx: ValueRef, heap: heap) {
assert!(heap != heap_exchange); assert!(heap != heap_exchange);
if heap == heap_managed_unique { if heap == heap_managed_unique {
// In cases where we are looking at a unique-typed allocation in the // In cases where we are looking at a unique-typed allocation in the
@ -597,12 +605,13 @@ pub fn maybe_name_value(cx: &CrateContext, v: ValueRef, s: &str) {
pub enum scalar_type { nil_type, signed_int, unsigned_int, floating_point, } pub enum scalar_type { nil_type, signed_int, unsigned_int, floating_point, }
// NB: This produces an i1, not a Rust bool (i8). // NB: This produces an i1, not a Rust bool (i8).
pub fn compare_scalar_types(cx: @Block, pub fn compare_scalar_types<'a>(
cx: &'a Block<'a>,
lhs: ValueRef, lhs: ValueRef,
rhs: ValueRef, rhs: ValueRef,
t: ty::t, t: ty::t,
op: ast::BinOp) op: ast::BinOp)
-> Result { -> Result<'a> {
let f = |a| compare_scalar_values(cx, lhs, rhs, a, op); let f = |a| compare_scalar_values(cx, lhs, rhs, a, op);
match ty::get(t).sty { match ty::get(t).sty {
@ -629,14 +638,15 @@ pub fn compare_scalar_types(cx: @Block,
// A helper function to do the actual comparison of scalar values. // A helper function to do the actual comparison of scalar values.
pub fn compare_scalar_values(cx: @Block, pub fn compare_scalar_values<'a>(
cx: &'a Block<'a>,
lhs: ValueRef, lhs: ValueRef,
rhs: ValueRef, rhs: ValueRef,
nt: scalar_type, nt: scalar_type,
op: ast::BinOp) op: ast::BinOp)
-> ValueRef { -> ValueRef {
let _icx = push_ctxt("compare_scalar_values"); let _icx = push_ctxt("compare_scalar_values");
fn die(cx: @Block) -> ! { fn die(cx: &Block) -> ! {
cx.tcx().sess.bug("compare_scalar_values: must be a\ cx.tcx().sess.bug("compare_scalar_values: must be a\
comparison operator"); comparison operator");
} }
@ -690,25 +700,41 @@ pub fn compare_scalar_values(cx: @Block,
} }
} }
pub type val_and_ty_fn<'a> = 'a |@Block, ValueRef, ty::t| pub type val_and_ty_fn<'r,'b> =
-> @Block; 'r |&'b Block<'b>, ValueRef, ty::t| -> &'b Block<'b>;
pub fn load_inbounds(cx: @Block, p: ValueRef, idxs: &[uint]) -> ValueRef { pub fn load_inbounds<'a>(cx: &'a Block<'a>, p: ValueRef, idxs: &[uint])
-> ValueRef {
return Load(cx, GEPi(cx, p, idxs)); return Load(cx, GEPi(cx, p, idxs));
} }
pub fn store_inbounds(cx: @Block, v: ValueRef, p: ValueRef, idxs: &[uint]) { pub fn store_inbounds<'a>(
cx: &'a Block<'a>,
v: ValueRef,
p: ValueRef,
idxs: &[uint]) {
Store(cx, v, GEPi(cx, p, idxs)); Store(cx, v, GEPi(cx, p, idxs));
} }
// Iterates through the elements of a structural type. // Iterates through the elements of a structural type.
pub fn iter_structural_ty(cx: @Block, av: ValueRef, t: ty::t, pub fn iter_structural_ty<'r,
f: val_and_ty_fn) -> @Block { 'b>(
cx: &'b Block<'b>,
av: ValueRef,
t: ty::t,
f: val_and_ty_fn<'r,'b>)
-> &'b Block<'b> {
let _icx = push_ctxt("iter_structural_ty"); let _icx = push_ctxt("iter_structural_ty");
fn iter_variant(cx: @Block, repr: &adt::Repr, av: ValueRef, fn iter_variant<'r,
'b>(
cx: &'b Block<'b>,
repr: &adt::Repr,
av: ValueRef,
variant: @ty::VariantInfo, variant: @ty::VariantInfo,
tps: &[ty::t], f: val_and_ty_fn) -> @Block { tps: &[ty::t],
f: val_and_ty_fn<'r,'b>)
-> &'b Block<'b> {
let _icx = push_ctxt("iter_variant"); let _icx = push_ctxt("iter_variant");
let tcx = cx.tcx(); let tcx = cx.tcx();
let mut cx = cx; let mut cx = cx;
@ -794,8 +820,12 @@ pub fn iter_structural_ty(cx: @Block, av: ValueRef, t: ty::t,
return cx; return cx;
} }
pub fn cast_shift_expr_rhs(cx: @Block, op: ast::BinOp, pub fn cast_shift_expr_rhs<'a>(
lhs: ValueRef, rhs: ValueRef) -> ValueRef { cx: &'a Block<'a>,
op: ast::BinOp,
lhs: ValueRef,
rhs: ValueRef)
-> ValueRef {
cast_shift_rhs(op, lhs, rhs, cast_shift_rhs(op, lhs, rhs,
|a,b| Trunc(cx, a, b), |a,b| Trunc(cx, a, b),
|a,b| ZExt(cx, a, b)) |a,b| ZExt(cx, a, b))
@ -836,8 +866,13 @@ pub fn cast_shift_rhs(op: ast::BinOp,
} }
} }
pub fn fail_if_zero(cx: @Block, span: Span, divrem: ast::BinOp, pub fn fail_if_zero<'a>(
rhs: ValueRef, rhs_t: ty::t) -> @Block { cx: &'a Block<'a>,
span: Span,
divrem: ast::BinOp,
rhs: ValueRef,
rhs_t: ty::t)
-> &'a Block<'a> {
let text = if divrem == ast::BiDiv { let text = if divrem == ast::BiDiv {
@"attempted to divide by zero" @"attempted to divide by zero"
} else { } else {
@ -895,12 +930,13 @@ pub fn trans_external_path(ccx: &CrateContext, did: ast::DefId, t: ty::t) -> Val
} }
} }
pub fn invoke(bcx: @Block, pub fn invoke<'a>(
bcx: &'a Block<'a>,
llfn: ValueRef, llfn: ValueRef,
llargs: ~[ValueRef], llargs: ~[ValueRef],
attributes: &[(uint, lib::llvm::Attribute)], attributes: &[(uint, lib::llvm::Attribute)],
call_info: Option<NodeInfo>) call_info: Option<NodeInfo>)
-> (ValueRef, @Block) { -> (ValueRef, &'a Block<'a>) {
let _icx = push_ctxt("invoke_"); let _icx = push_ctxt("invoke_");
if bcx.unreachable.get() { if bcx.unreachable.get() {
return (C_null(Type::i8()), bcx); return (C_null(Type::i8()), bcx);
@ -954,7 +990,7 @@ pub fn invoke(bcx: @Block,
} }
} }
pub fn need_invoke(bcx: @Block) -> bool { pub fn need_invoke(bcx: &Block) -> bool {
if bcx.ccx().sess.no_landing_pads() { if bcx.ccx().sess.no_landing_pads() {
return false; return false;
} }
@ -997,7 +1033,7 @@ pub fn need_invoke(bcx: @Block) -> bool {
} }
} }
pub fn have_cached_lpad(bcx: @Block) -> bool { pub fn have_cached_lpad(bcx: &Block) -> bool {
let mut res = false; let mut res = false;
in_lpad_scope_cx(bcx, |inf| { in_lpad_scope_cx(bcx, |inf| {
match inf.landing_pad.get() { match inf.landing_pad.get() {
@ -1008,7 +1044,7 @@ pub fn have_cached_lpad(bcx: @Block) -> bool {
return res; return res;
} }
pub fn in_lpad_scope_cx(bcx: @Block, f: |si: &ScopeInfo|) { pub fn in_lpad_scope_cx<'a>(bcx: &'a Block<'a>, f: |si: &'a ScopeInfo<'a>|) {
let mut bcx = bcx; let mut bcx = bcx;
let mut cur_scope = bcx.scope.get(); let mut cur_scope = bcx.scope.get();
loop { loop {
@ -1028,7 +1064,7 @@ pub fn in_lpad_scope_cx(bcx: @Block, f: |si: &ScopeInfo|) {
} }
} }
pub fn get_landing_pad(bcx: @Block) -> BasicBlockRef { pub fn get_landing_pad<'a>(bcx: &'a Block<'a>) -> BasicBlockRef {
let _icx = push_ctxt("get_landing_pad"); let _icx = push_ctxt("get_landing_pad");
let mut cached = None; let mut cached = None;
@ -1074,7 +1110,8 @@ pub fn get_landing_pad(bcx: @Block) -> BasicBlockRef {
return pad_bcx.llbb; return pad_bcx.llbb;
} }
pub fn find_bcx_for_scope(bcx: @Block, scope_id: ast::NodeId) -> @Block { pub fn find_bcx_for_scope<'a>(bcx: &'a Block<'a>, scope_id: ast::NodeId)
-> &'a Block<'a> {
let mut bcx_sid = bcx; let mut bcx_sid = bcx;
let mut cur_scope = bcx_sid.scope.get(); let mut cur_scope = bcx_sid.scope.get();
loop { loop {
@ -1103,7 +1140,7 @@ pub fn find_bcx_for_scope(bcx: @Block, scope_id: ast::NodeId) -> @Block {
} }
pub fn do_spill(bcx: @Block, v: ValueRef, t: ty::t) -> ValueRef { pub fn do_spill(bcx: &Block, v: ValueRef, t: ty::t) -> ValueRef {
if ty::type_is_bot(t) { if ty::type_is_bot(t) {
return C_null(Type::i8p()); return C_null(Type::i8p());
} }
@ -1114,31 +1151,32 @@ pub fn do_spill(bcx: @Block, v: ValueRef, t: ty::t) -> ValueRef {
// Since this function does *not* root, it is the caller's responsibility to // Since this function does *not* root, it is the caller's responsibility to
// ensure that the referent is pointed to by a root. // ensure that the referent is pointed to by a root.
pub fn do_spill_noroot(cx: @Block, v: ValueRef) -> ValueRef { pub fn do_spill_noroot(cx: &Block, v: ValueRef) -> ValueRef {
let llptr = alloca(cx, val_ty(v), ""); let llptr = alloca(cx, val_ty(v), "");
Store(cx, v, llptr); Store(cx, v, llptr);
return llptr; return llptr;
} }
pub fn spill_if_immediate(cx: @Block, v: ValueRef, t: ty::t) -> ValueRef { pub fn spill_if_immediate(cx: &Block, v: ValueRef, t: ty::t) -> ValueRef {
let _icx = push_ctxt("spill_if_immediate"); let _icx = push_ctxt("spill_if_immediate");
if type_is_immediate(cx.ccx(), t) { return do_spill(cx, v, t); } if type_is_immediate(cx.ccx(), t) { return do_spill(cx, v, t); }
return v; return v;
} }
pub fn load_if_immediate(cx: @Block, v: ValueRef, t: ty::t) -> ValueRef { pub fn load_if_immediate(cx: &Block, v: ValueRef, t: ty::t) -> ValueRef {
let _icx = push_ctxt("load_if_immediate"); let _icx = push_ctxt("load_if_immediate");
if type_is_immediate(cx.ccx(), t) { return Load(cx, v); } if type_is_immediate(cx.ccx(), t) { return Load(cx, v); }
return v; return v;
} }
pub fn ignore_lhs(_bcx: @Block, local: &ast::Local) -> bool { pub fn ignore_lhs(_bcx: &Block, local: &ast::Local) -> bool {
match local.pat.node { match local.pat.node {
ast::PatWild => true, _ => false ast::PatWild => true, _ => false
} }
} }
pub fn init_local(bcx: @Block, local: &ast::Local) -> @Block { pub fn init_local<'a>(bcx: &'a Block<'a>, local: &ast::Local)
-> &'a Block<'a> {
debug!("init_local(bcx={}, local.id={:?})", debug!("init_local(bcx={}, local.id={:?})",
bcx.to_str(), local.id); bcx.to_str(), local.id);
@ -1159,7 +1197,7 @@ pub fn init_local(bcx: @Block, local: &ast::Local) -> @Block {
_match::store_local(bcx, local.pat, local.init) _match::store_local(bcx, local.pat, local.init)
} }
pub fn trans_stmt(cx: @Block, s: &ast::Stmt) -> @Block { pub fn trans_stmt<'a>(cx: &'a Block<'a>, s: &ast::Stmt) -> &'a Block<'a> {
let _icx = push_ctxt("trans_stmt"); let _icx = push_ctxt("trans_stmt");
debug!("trans_stmt({})", stmt_to_str(s, cx.tcx().sess.intr())); debug!("trans_stmt({})", stmt_to_str(s, cx.tcx().sess.intr()));
@ -1192,22 +1230,19 @@ pub fn trans_stmt(cx: @Block, s: &ast::Stmt) -> @Block {
// You probably don't want to use this one. See the // You probably don't want to use this one. See the
// next three functions instead. // next three functions instead.
pub fn new_block(cx: @FunctionContext, pub fn new_block<'a>(
parent: Option<@Block>, cx: &'a FunctionContext<'a>,
scope: Option<@ScopeInfo>, parent: Option<&'a Block<'a>>,
scope: Option<&'a ScopeInfo<'a>>,
is_lpad: bool, is_lpad: bool,
name: &str, name: &str,
opt_node_info: Option<NodeInfo>) opt_node_info: Option<NodeInfo>)
-> @Block { -> &'a Block<'a> {
unsafe { unsafe {
let llbb = name.with_c_str(|buf| { let llbb = name.with_c_str(|buf| {
llvm::LLVMAppendBasicBlockInContext(cx.ccx.llcx, cx.llfn, buf) llvm::LLVMAppendBasicBlockInContext(cx.ccx.llcx, cx.llfn, buf)
}); });
let bcx = @Block::new(llbb, let bcx = Block::new(llbb, parent, is_lpad, opt_node_info, cx);
parent,
is_lpad,
opt_node_info,
cx);
bcx.scope.set(scope); bcx.scope.set(scope);
for cx in parent.iter() { for cx in parent.iter() {
if cx.unreachable.get() { if cx.unreachable.get() {
@ -1219,10 +1254,12 @@ pub fn new_block(cx: @FunctionContext,
} }
} }
pub fn simple_block_scope(parent: Option<@ScopeInfo>, pub fn simple_block_scope<'a>(
fcx: &'a FunctionContext<'a>,
parent: Option<&'a ScopeInfo<'a>>,
node_info: Option<NodeInfo>) node_info: Option<NodeInfo>)
-> @ScopeInfo { -> &'a ScopeInfo<'a> {
@ScopeInfo { fcx.scope_info_arena.alloc(ScopeInfo {
parent: parent, parent: parent,
loop_break: None, loop_break: None,
loop_label: None, loop_label: None,
@ -1230,29 +1267,45 @@ pub fn simple_block_scope(parent: Option<@ScopeInfo>,
cleanup_paths: RefCell::new(~[]), cleanup_paths: RefCell::new(~[]),
landing_pad: Cell::new(None), landing_pad: Cell::new(None),
node_info: node_info, node_info: node_info,
} })
} }
// Use this when you're at the top block of a function or the like. // Use this when you're at the top block of a function or the like.
pub fn top_scope_block(fcx: @FunctionContext, opt_node_info: Option<NodeInfo>) pub fn top_scope_block<'a>(
-> @Block { fcx: &'a FunctionContext<'a>,
return new_block(fcx, None, Some(simple_block_scope(None, opt_node_info)), false, opt_node_info: Option<NodeInfo>)
"function top level", opt_node_info); -> &'a Block<'a> {
new_block(fcx,
None,
Some(simple_block_scope(fcx, None, opt_node_info)),
false,
"function top level",
opt_node_info)
} }
pub fn scope_block(bcx: @Block, pub fn scope_block<'a>(
bcx: &'a Block<'a>,
opt_node_info: Option<NodeInfo>, opt_node_info: Option<NodeInfo>,
n: &str) -> @Block { n: &str)
return new_block(bcx.fcx, Some(bcx), Some(simple_block_scope(None, opt_node_info)), bcx.is_lpad, -> &'a Block<'a> {
n, opt_node_info); new_block(bcx.fcx,
Some(bcx),
Some(simple_block_scope(bcx.fcx, None, opt_node_info)),
bcx.is_lpad,
n,
opt_node_info)
} }
pub fn loop_scope_block(bcx: @Block, pub fn loop_scope_block<'a>(
loop_break: @Block, bcx: &'a Block<'a>,
loop_break: &'a Block<'a>,
loop_label: Option<Name>, loop_label: Option<Name>,
n: &str, n: &str,
opt_node_info: Option<NodeInfo>) -> @Block { opt_node_info: Option<NodeInfo>)
return new_block(bcx.fcx, Some(bcx), Some(@ScopeInfo { -> &'a Block<'a> {
new_block(bcx.fcx,
Some(bcx),
Some(bcx.fcx.scope_info_arena.alloc(ScopeInfo {
parent: None, parent: None,
loop_break: Some(loop_break), loop_break: Some(loop_break),
loop_label: loop_label, loop_label: loop_label,
@ -1260,21 +1313,28 @@ pub fn loop_scope_block(bcx: @Block,
cleanup_paths: RefCell::new(~[]), cleanup_paths: RefCell::new(~[]),
landing_pad: Cell::new(None), landing_pad: Cell::new(None),
node_info: opt_node_info, node_info: opt_node_info,
}), bcx.is_lpad, n, opt_node_info); })),
bcx.is_lpad,
n,
opt_node_info)
} }
// Use this when creating a block for the inside of a landing pad. // Use this when creating a block for the inside of a landing pad.
pub fn lpad_block(bcx: @Block, n: &str) -> @Block { pub fn lpad_block<'a>(bcx: &'a Block<'a>, n: &str) -> &'a Block<'a> {
new_block(bcx.fcx, Some(bcx), None, true, n, None) new_block(bcx.fcx, Some(bcx), None, true, n, None)
} }
// Use this when you're making a general CFG BB within a scope. // Use this when you're making a general CFG BB within a scope.
pub fn sub_block(bcx: @Block, n: &str) -> @Block { pub fn sub_block<'a>(bcx: &'a Block<'a>, n: &str) -> &'a Block<'a> {
new_block(bcx.fcx, Some(bcx), None, bcx.is_lpad, n, None) new_block(bcx.fcx, Some(bcx), None, bcx.is_lpad, n, None)
} }
pub fn raw_block(fcx: @FunctionContext, is_lpad: bool, llbb: BasicBlockRef) -> @Block { pub fn raw_block<'a>(
@Block::new(llbb, None, is_lpad, None, fcx) fcx: &'a FunctionContext<'a>,
is_lpad: bool,
llbb: BasicBlockRef)
-> &'a Block<'a> {
Block::new(llbb, None, is_lpad, None, fcx)
} }
@ -1285,14 +1345,16 @@ pub fn raw_block(fcx: @FunctionContext, is_lpad: bool, llbb: BasicBlockRef) -> @
// need to make sure those variables go out of scope when the block ends. We // need to make sure those variables go out of scope when the block ends. We
// do that by running a 'cleanup' function for each variable. // do that by running a 'cleanup' function for each variable.
// trans_block_cleanups runs all the cleanup functions for the block. // trans_block_cleanups runs all the cleanup functions for the block.
pub fn trans_block_cleanups(bcx: @Block, cleanups: ~[cleanup]) -> @Block { pub fn trans_block_cleanups<'a>(bcx: &'a Block<'a>, cleanups: ~[cleanup])
-> &'a Block<'a> {
trans_block_cleanups_(bcx, cleanups, false) trans_block_cleanups_(bcx, cleanups, false)
} }
pub fn trans_block_cleanups_(bcx: @Block, pub fn trans_block_cleanups_<'a>(
bcx: &'a Block<'a>,
cleanups: &[cleanup], cleanups: &[cleanup],
/* cleanup_cx: block, */ is_lpad: bool)
is_lpad: bool) -> @Block { -> &'a Block<'a> {
let _icx = push_ctxt("trans_block_cleanups"); let _icx = push_ctxt("trans_block_cleanups");
// NB: Don't short-circuit even if this block is unreachable because // NB: Don't short-circuit even if this block is unreachable because
// GC-based cleanup needs to the see that the roots are live. // GC-based cleanup needs to the see that the roots are live.
@ -1318,7 +1380,8 @@ pub fn trans_block_cleanups_(bcx: @Block,
// In the last argument, Some(block) mean jump to this block, and none means // In the last argument, Some(block) mean jump to this block, and none means
// this is a landing pad and leaving should be accomplished with a resume // this is a landing pad and leaving should be accomplished with a resume
// instruction. // instruction.
pub fn cleanup_and_leave(bcx: @Block, pub fn cleanup_and_leave<'a>(
bcx: &'a Block<'a>,
upto: Option<BasicBlockRef>, upto: Option<BasicBlockRef>,
leave: Option<BasicBlockRef>) { leave: Option<BasicBlockRef>) {
let _icx = push_ctxt("cleanup_and_leave"); let _icx = push_ctxt("cleanup_and_leave");
@ -1398,7 +1461,8 @@ pub fn cleanup_and_leave(bcx: @Block,
} }
} }
pub fn cleanup_block(bcx: @Block, upto: Option<BasicBlockRef>) -> @Block{ pub fn cleanup_block<'a>(bcx: &'a Block<'a>, upto: Option<BasicBlockRef>)
-> &'a Block<'a> {
let _icx = push_ctxt("cleanup_block"); let _icx = push_ctxt("cleanup_block");
let mut cur = bcx; let mut cur = bcx;
let mut bcx = bcx; let mut bcx = bcx;
@ -1431,12 +1495,16 @@ pub fn cleanup_block(bcx: @Block, upto: Option<BasicBlockRef>) -> @Block{
bcx bcx
} }
pub fn cleanup_and_Br(bcx: @Block, upto: @Block, target: BasicBlockRef) { pub fn cleanup_and_Br<'a>(
bcx: &'a Block<'a>,
upto: &'a Block<'a>,
target: BasicBlockRef) {
let _icx = push_ctxt("cleanup_and_Br"); let _icx = push_ctxt("cleanup_and_Br");
cleanup_and_leave(bcx, Some(upto.llbb), Some(target)); cleanup_and_leave(bcx, Some(upto.llbb), Some(target));
} }
pub fn leave_block(bcx: @Block, out_of: @Block) -> @Block { pub fn leave_block<'a>(bcx: &'a Block<'a>, out_of: &'a Block<'a>)
-> &'a Block<'a> {
let _icx = push_ctxt("leave_block"); let _icx = push_ctxt("leave_block");
let next_cx = sub_block(block_parent(out_of), "next"); let next_cx = sub_block(block_parent(out_of), "next");
if bcx.unreachable.get() { if bcx.unreachable.get() {
@ -1446,18 +1514,19 @@ pub fn leave_block(bcx: @Block, out_of: @Block) -> @Block {
next_cx next_cx
} }
pub fn with_scope(bcx: @Block, pub fn with_scope<'a>(
bcx: &'a Block<'a>,
opt_node_info: Option<NodeInfo>, opt_node_info: Option<NodeInfo>,
name: &str, name: &str,
f: |@Block| -> @Block) f: |&'a Block<'a>| -> &'a Block<'a>)
-> @Block { -> &'a Block<'a> {
let _icx = push_ctxt("with_scope"); let _icx = push_ctxt("with_scope");
debug!("with_scope(bcx={}, opt_node_info={:?}, name={})", debug!("with_scope(bcx={}, opt_node_info={:?}, name={})",
bcx.to_str(), opt_node_info, name); bcx.to_str(), opt_node_info, name);
let _indenter = indenter(); let _indenter = indenter();
let scope = simple_block_scope(bcx.scope.get(), opt_node_info); let scope = simple_block_scope(bcx.fcx, bcx.scope.get(), opt_node_info);
bcx.scope.set(Some(scope)); bcx.scope.set(Some(scope));
let ret = f(bcx); let ret = f(bcx);
let ret = trans_block_cleanups_(ret, scope.cleanups.get(), false); let ret = trans_block_cleanups_(ret, scope.cleanups.get(), false);
@ -1465,14 +1534,15 @@ pub fn with_scope(bcx: @Block,
ret ret
} }
pub fn with_scope_result(bcx: @Block, pub fn with_scope_result<'a>(
bcx: &'a Block<'a>,
opt_node_info: Option<NodeInfo>, opt_node_info: Option<NodeInfo>,
_name: &str, _name: &str,
f: |@Block| -> Result) f: |&'a Block<'a>| -> Result<'a>)
-> Result { -> Result<'a> {
let _icx = push_ctxt("with_scope_result"); let _icx = push_ctxt("with_scope_result");
let scope = simple_block_scope(bcx.scope.get(), opt_node_info); let scope = simple_block_scope(bcx.fcx, bcx.scope.get(), opt_node_info);
bcx.scope.set(Some(scope)); bcx.scope.set(Some(scope));
let Result { bcx: out_bcx, val } = f(bcx); let Result { bcx: out_bcx, val } = f(bcx);
let out_bcx = trans_block_cleanups_(out_bcx, scope.cleanups.get(), false); let out_bcx = trans_block_cleanups_(out_bcx, scope.cleanups.get(), false);
@ -1481,11 +1551,12 @@ pub fn with_scope_result(bcx: @Block,
rslt(out_bcx, val) rslt(out_bcx, val)
} }
pub fn with_scope_datumblock(bcx: @Block, pub fn with_scope_datumblock<'a>(
bcx: &'a Block<'a>,
opt_node_info: Option<NodeInfo>, opt_node_info: Option<NodeInfo>,
name: &str, name: &str,
f: |@Block| -> datum::DatumBlock) f: |&'a Block| -> datum::DatumBlock<'a>)
-> datum::DatumBlock { -> datum::DatumBlock<'a> {
use middle::trans::datum::DatumBlock; use middle::trans::datum::DatumBlock;
let _icx = push_ctxt("with_scope_result"); let _icx = push_ctxt("with_scope_result");
@ -1509,10 +1580,11 @@ pub fn block_locals(b: &ast::Block, it: |@ast::Local|) {
} }
} }
pub fn with_cond(bcx: @Block, pub fn with_cond<'a>(
bcx: &'a Block<'a>,
val: ValueRef, val: ValueRef,
f: |@Block| -> @Block) f: |&'a Block<'a>| -> &'a Block<'a>)
-> @Block { -> &'a Block<'a> {
let _icx = push_ctxt("with_cond"); let _icx = push_ctxt("with_cond");
let next_cx = base::sub_block(bcx, "next"); let next_cx = base::sub_block(bcx, "next");
let cond_cx = base::sub_block(bcx, "cond"); let cond_cx = base::sub_block(bcx, "cond");
@ -1524,7 +1596,7 @@ pub fn with_cond(bcx: @Block,
next_cx next_cx
} }
pub fn call_memcpy(cx: @Block, dst: ValueRef, src: ValueRef, n_bytes: ValueRef, align: u32) { pub fn call_memcpy(cx: &Block, dst: ValueRef, src: ValueRef, n_bytes: ValueRef, align: u32) {
let _icx = push_ctxt("call_memcpy"); let _icx = push_ctxt("call_memcpy");
let ccx = cx.ccx(); let ccx = cx.ccx();
let key = match ccx.sess.targ_cfg.arch { let key = match ccx.sess.targ_cfg.arch {
@ -1540,7 +1612,7 @@ pub fn call_memcpy(cx: @Block, dst: ValueRef, src: ValueRef, n_bytes: ValueRef,
Call(cx, memcpy, [dst_ptr, src_ptr, size, align, volatile], []); Call(cx, memcpy, [dst_ptr, src_ptr, size, align, volatile], []);
} }
pub fn memcpy_ty(bcx: @Block, dst: ValueRef, src: ValueRef, t: ty::t) { pub fn memcpy_ty(bcx: &Block, dst: ValueRef, src: ValueRef, t: ty::t) {
let _icx = push_ctxt("memcpy_ty"); let _icx = push_ctxt("memcpy_ty");
let ccx = bcx.ccx(); let ccx = bcx.ccx();
if ty::type_is_structural(t) { if ty::type_is_structural(t) {
@ -1553,7 +1625,7 @@ pub fn memcpy_ty(bcx: @Block, dst: ValueRef, src: ValueRef, t: ty::t) {
} }
} }
pub fn zero_mem(cx: @Block, llptr: ValueRef, t: ty::t) { pub fn zero_mem(cx: &Block, llptr: ValueRef, t: ty::t) {
if cx.unreachable.get() { return; } if cx.unreachable.get() { return; }
let _icx = push_ctxt("zero_mem"); let _icx = push_ctxt("zero_mem");
let bcx = cx; let bcx = cx;
@ -1585,7 +1657,7 @@ pub fn memzero(b: &Builder, llptr: ValueRef, ty: Type) {
b.call(llintrinsicfn, [llptr, llzeroval, size, align, volatile], []); b.call(llintrinsicfn, [llptr, llzeroval, size, align, volatile], []);
} }
pub fn alloc_ty(bcx: @Block, t: ty::t, name: &str) -> ValueRef { pub fn alloc_ty(bcx: &Block, t: ty::t, name: &str) -> ValueRef {
let _icx = push_ctxt("alloc_ty"); let _icx = push_ctxt("alloc_ty");
let ccx = bcx.ccx(); let ccx = bcx.ccx();
let ty = type_of::type_of(ccx, t); let ty = type_of::type_of(ccx, t);
@ -1594,11 +1666,11 @@ pub fn alloc_ty(bcx: @Block, t: ty::t, name: &str) -> ValueRef {
return val; return val;
} }
pub fn alloca(cx: @Block, ty: Type, name: &str) -> ValueRef { pub fn alloca(cx: &Block, ty: Type, name: &str) -> ValueRef {
alloca_maybe_zeroed(cx, ty, name, false) alloca_maybe_zeroed(cx, ty, name, false)
} }
pub fn alloca_maybe_zeroed(cx: @Block, ty: Type, name: &str, zero: bool) -> ValueRef { pub fn alloca_maybe_zeroed(cx: &Block, ty: Type, name: &str, zero: bool) -> ValueRef {
let _icx = push_ctxt("alloca"); let _icx = push_ctxt("alloca");
if cx.unreachable.get() { if cx.unreachable.get() {
unsafe { unsafe {
@ -1615,7 +1687,7 @@ pub fn alloca_maybe_zeroed(cx: @Block, ty: Type, name: &str, zero: bool) -> Valu
p p
} }
pub fn arrayalloca(cx: @Block, ty: Type, v: ValueRef) -> ValueRef { pub fn arrayalloca(cx: &Block, ty: Type, v: ValueRef) -> ValueRef {
let _icx = push_ctxt("arrayalloca"); let _icx = push_ctxt("arrayalloca");
if cx.unreachable.get() { if cx.unreachable.get() {
unsafe { unsafe {
@ -1650,7 +1722,8 @@ pub fn mk_return_basic_block(llfn: ValueRef) -> BasicBlockRef {
// Creates and returns space for, or returns the argument representing, the // Creates and returns space for, or returns the argument representing, the
// slot where the return value of the function must go. // slot where the return value of the function must go.
pub fn make_return_pointer(fcx: @FunctionContext, output_type: ty::t) -> ValueRef { pub fn make_return_pointer(fcx: &FunctionContext, output_type: ty::t)
-> ValueRef {
unsafe { unsafe {
if type_of::return_uses_outptr(fcx.ccx, output_type) { if type_of::return_uses_outptr(fcx.ccx, output_type) {
llvm::LLVMGetParam(fcx.llfn, 0) llvm::LLVMGetParam(fcx.llfn, 0)
@ -1668,16 +1741,17 @@ pub fn make_return_pointer(fcx: @FunctionContext, output_type: ty::t) -> ValueRe
// - create_llargs_for_fn_args. // - create_llargs_for_fn_args.
// - new_fn_ctxt // - new_fn_ctxt
// - trans_args // - trans_args
//
// Be warned! You must call `init_function` before doing anything with the
// returned function context.
pub fn new_fn_ctxt_w_id(ccx: @CrateContext, pub fn new_fn_ctxt_w_id(ccx: @CrateContext,
path: path, path: path,
llfndecl: ValueRef, llfndecl: ValueRef,
id: ast::NodeId, id: ast::NodeId,
output_type: ty::t, output_type: ty::t,
skip_retptr: bool,
param_substs: Option<@param_substs>, param_substs: Option<@param_substs>,
opt_node_info: Option<NodeInfo>,
sp: Option<Span>) sp: Option<Span>)
-> @FunctionContext { -> FunctionContext {
for p in param_substs.iter() { p.validate(); } for p in param_substs.iter() { p.validate(); }
debug!("new_fn_ctxt_w_id(path={}, id={:?}, \ debug!("new_fn_ctxt_w_id(path={}, id={:?}, \
@ -1695,7 +1769,7 @@ pub fn new_fn_ctxt_w_id(ccx: @CrateContext,
let uses_outptr = type_of::return_uses_outptr(ccx, substd_output_type); let uses_outptr = type_of::return_uses_outptr(ccx, substd_output_type);
let debug_context = debuginfo::create_function_debug_context(ccx, id, param_substs, llfndecl); let debug_context = debuginfo::create_function_debug_context(ccx, id, param_substs, llfndecl);
let fcx = @FunctionContext { let fcx = FunctionContext {
llfn: llfndecl, llfn: llfndecl,
llenv: unsafe { llenv: unsafe {
Cell::new(llvm::LLVMGetUndef(Type::i8p().to_ref())) Cell::new(llvm::LLVMGetUndef(Type::i8p().to_ref()))
@ -1714,6 +1788,8 @@ pub fn new_fn_ctxt_w_id(ccx: @CrateContext,
param_substs: param_substs, param_substs: param_substs,
span: sp, span: sp,
path: path, path: path,
block_arena: TypedArena::new(),
scope_info_arena: TypedArena::new(),
ccx: ccx, ccx: ccx,
debug_context: debug_context, debug_context: debug_context,
}; };
@ -1721,6 +1797,17 @@ pub fn new_fn_ctxt_w_id(ccx: @CrateContext,
llvm::LLVMGetParam(llfndecl, fcx.env_arg_pos() as c_uint) llvm::LLVMGetParam(llfndecl, fcx.env_arg_pos() as c_uint)
}); });
fcx
}
/// Performs setup on a newly created function, creating the entry scope block
/// and allocating space for the return pointer.
pub fn init_function<'a>(
fcx: &'a FunctionContext<'a>,
skip_retptr: bool,
output_type: ty::t,
param_substs: Option<@param_substs>,
opt_node_info: Option<NodeInfo>) {
unsafe { unsafe {
let entry_bcx = top_scope_block(fcx, opt_node_info); let entry_bcx = top_scope_block(fcx, opt_node_info);
Load(entry_bcx, C_null(Type::i8p())); Load(entry_bcx, C_null(Type::i8p()));
@ -1730,10 +1817,20 @@ pub fn new_fn_ctxt_w_id(ccx: @CrateContext,
llvm::LLVMGetFirstInstruction(entry_bcx.llbb))); llvm::LLVMGetFirstInstruction(entry_bcx.llbb)));
} }
if !ty::type_is_voidish(ccx.tcx, substd_output_type) { let substd_output_type = match param_substs {
None => output_type,
Some(substs) => {
ty::subst_tps(fcx.ccx.tcx,
substs.tys,
substs.self_ty,
output_type)
}
};
if !ty::type_is_voidish(fcx.ccx.tcx, substd_output_type) {
// If the function returns nil/bot, there is no real return // If the function returns nil/bot, there is no real return
// value, so do not set `llretptr`. // value, so do not set `llretptr`.
if !skip_retptr || uses_outptr { if !skip_retptr || fcx.caller_expects_out_pointer {
// Otherwise, we normally allocate the llretptr, unless we // Otherwise, we normally allocate the llretptr, unless we
// have been instructed to skip it for immediate return // have been instructed to skip it for immediate return
// values. // values.
@ -1741,7 +1838,6 @@ pub fn new_fn_ctxt_w_id(ccx: @CrateContext,
substd_output_type))); substd_output_type)));
} }
} }
fcx
} }
pub fn new_fn_ctxt(ccx: @CrateContext, pub fn new_fn_ctxt(ccx: @CrateContext,
@ -1749,8 +1845,10 @@ pub fn new_fn_ctxt(ccx: @CrateContext,
llfndecl: ValueRef, llfndecl: ValueRef,
output_type: ty::t, output_type: ty::t,
sp: Option<Span>) sp: Option<Span>)
-> @FunctionContext { -> FunctionContext {
new_fn_ctxt_w_id(ccx, path, llfndecl, -1, output_type, false, None, None, sp) // FIXME(#11385): Do not call `init_function` here; it will typecheck
// but segfault.
new_fn_ctxt_w_id(ccx, path, llfndecl, -1, output_type, None, sp)
} }
// NB: must keep 4 fns in sync: // NB: must keep 4 fns in sync:
@ -1767,7 +1865,7 @@ pub fn new_fn_ctxt(ccx: @CrateContext,
// spaces that have been created for them (by code in the llallocas field of // spaces that have been created for them (by code in the llallocas field of
// the function's fn_ctxt). create_llargs_for_fn_args populates the llargs // the function's fn_ctxt). create_llargs_for_fn_args populates the llargs
// field of the fn_ctxt with // field of the fn_ctxt with
pub fn create_llargs_for_fn_args(cx: @FunctionContext, pub fn create_llargs_for_fn_args(cx: &FunctionContext,
self_arg: self_arg, self_arg: self_arg,
args: &[ast::arg]) args: &[ast::arg])
-> ~[ValueRef] { -> ~[ValueRef] {
@ -1791,11 +1889,13 @@ pub fn create_llargs_for_fn_args(cx: @FunctionContext,
}) })
} }
pub fn copy_args_to_allocas(fcx: @FunctionContext, pub fn copy_args_to_allocas<'a>(
bcx: @Block, fcx: &FunctionContext<'a>,
bcx: &'a Block<'a>,
args: &[ast::arg], args: &[ast::arg],
raw_llargs: &[ValueRef], raw_llargs: &[ValueRef],
arg_tys: &[ty::t]) -> @Block { arg_tys: &[ty::t])
-> &'a Block<'a> {
debug!("copy_args_to_allocas: raw_llargs={} arg_tys={}", debug!("copy_args_to_allocas: raw_llargs={} arg_tys={}",
raw_llargs.llrepr(fcx.ccx), raw_llargs.llrepr(fcx.ccx),
arg_tys.repr(fcx.ccx.tcx)); arg_tys.repr(fcx.ccx.tcx));
@ -1855,7 +1955,7 @@ pub fn copy_args_to_allocas(fcx: @FunctionContext,
// Ties up the llstaticallocas -> llloadenv -> lltop edges, // Ties up the llstaticallocas -> llloadenv -> lltop edges,
// and builds the return block. // and builds the return block.
pub fn finish_fn(fcx: @FunctionContext, last_bcx: @Block) { pub fn finish_fn(fcx: &FunctionContext, last_bcx: &Block) {
let _icx = push_ctxt("finish_fn"); let _icx = push_ctxt("finish_fn");
let ret_cx = match fcx.llreturn.get() { let ret_cx = match fcx.llreturn.get() {
@ -1873,7 +1973,7 @@ pub fn finish_fn(fcx: @FunctionContext, last_bcx: @Block) {
} }
// Builds the return block for a function. // Builds the return block for a function.
pub fn build_return_block(fcx: &FunctionContext, ret_cx: @Block) { pub fn build_return_block(fcx: &FunctionContext, ret_cx: &Block) {
// Return the value if this function immediate; otherwise, return void. // Return the value if this function immediate; otherwise, return void.
if fcx.llretptr.get().is_none() || fcx.caller_expects_out_pointer { if fcx.llretptr.get().is_none() || fcx.caller_expects_out_pointer {
return RetVoid(ret_cx); return RetVoid(ret_cx);
@ -1916,7 +2016,7 @@ pub fn trans_closure(ccx: @CrateContext,
id: ast::NodeId, id: ast::NodeId,
_attributes: &[ast::Attribute], _attributes: &[ast::Attribute],
output_type: ty::t, output_type: ty::t,
maybe_load_env: |@FunctionContext|) { maybe_load_env: |&FunctionContext|) {
ccx.stats.n_closures.set(ccx.stats.n_closures.get() + 1); ccx.stats.n_closures.set(ccx.stats.n_closures.get() + 1);
let _icx = push_ctxt("trans_closure"); let _icx = push_ctxt("trans_closure");
@ -1930,10 +2030,9 @@ pub fn trans_closure(ccx: @CrateContext,
llfndecl, llfndecl,
id, id,
output_type, output_type,
false,
param_substs, param_substs,
body.info(),
Some(body.span)); Some(body.span));
init_function(&fcx, false, output_type, param_substs, body.info());
// Create the first basic block in the function and keep a handle on it to // Create the first basic block in the function and keep a handle on it to
// pass to finish_fn later. // pass to finish_fn later.
@ -1943,16 +2042,16 @@ pub fn trans_closure(ccx: @CrateContext,
// Set up arguments to the function. // Set up arguments to the function.
let arg_tys = ty::ty_fn_args(node_id_type(bcx, id)); let arg_tys = ty::ty_fn_args(node_id_type(bcx, id));
let raw_llargs = create_llargs_for_fn_args(fcx, self_arg, decl.inputs); let raw_llargs = create_llargs_for_fn_args(&fcx, self_arg, decl.inputs);
bcx = copy_args_to_allocas(fcx, bcx, decl.inputs, raw_llargs, arg_tys); bcx = copy_args_to_allocas(&fcx, bcx, decl.inputs, raw_llargs, arg_tys);
maybe_load_env(fcx); maybe_load_env(&fcx);
// Up until here, IR instructions for this function have explicitly not been annotated with // Up until here, IR instructions for this function have explicitly not been annotated with
// source code location, so we don't step into call setup code. From here on, source location // source code location, so we don't step into call setup code. From here on, source location
// emitting should be enabled. // emitting should be enabled.
debuginfo::start_emitting_source_locations(fcx); debuginfo::start_emitting_source_locations(&fcx);
// This call to trans_block is the place where we bridge between // This call to trans_block is the place where we bridge between
// translation calls that don't have a return value (trans_crate, // translation calls that don't have a return value (trans_crate,
@ -1980,7 +2079,7 @@ pub fn trans_closure(ccx: @CrateContext,
} }
// Insert the mandatory first few basic blocks before lltop. // Insert the mandatory first few basic blocks before lltop.
finish_fn(fcx, bcx); finish_fn(&fcx, bcx);
} }
// trans_fn: creates an LLVM function corresponding to a source language // trans_fn: creates an LLVM function corresponding to a source language
@ -2015,10 +2114,9 @@ pub fn trans_fn(ccx: @CrateContext,
|_fcx| { }); |_fcx| { });
} }
fn insert_synthetic_type_entries(bcx: @Block, fn insert_synthetic_type_entries(bcx: &Block,
fn_args: &[ast::arg], fn_args: &[ast::arg],
arg_tys: &[ty::t]) arg_tys: &[ty::t]) {
{
/*! /*!
* For tuple-like structs and enum-variants, we generate * For tuple-like structs and enum-variants, we generate
* synthetic AST nodes for the arguments. These have no types * synthetic AST nodes for the arguments. These have no types
@ -2143,19 +2241,18 @@ pub fn trans_enum_variant_or_tuple_like_struct<A:IdAndTy>(
llfndecl, llfndecl,
ctor_id, ctor_id,
result_ty, result_ty,
false,
param_substs, param_substs,
None,
None); None);
init_function(&fcx, false, result_ty, param_substs, None);
let arg_tys = ty::ty_fn_args(ctor_ty); let arg_tys = ty::ty_fn_args(ctor_ty);
let raw_llargs = create_llargs_for_fn_args(fcx, no_self, fn_args); let raw_llargs = create_llargs_for_fn_args(&fcx, no_self, fn_args);
let bcx = fcx.entry_bcx.get().unwrap(); let bcx = fcx.entry_bcx.get().unwrap();
insert_synthetic_type_entries(bcx, fn_args, arg_tys); insert_synthetic_type_entries(bcx, fn_args, arg_tys);
let bcx = copy_args_to_allocas(fcx, bcx, fn_args, raw_llargs, arg_tys); let bcx = copy_args_to_allocas(&fcx, bcx, fn_args, raw_llargs, arg_tys);
let repr = adt::represent_type(ccx, result_ty); let repr = adt::represent_type(ccx, result_ty);
adt::trans_start_init(bcx, repr, fcx.llretptr.get().unwrap(), disr); adt::trans_start_init(bcx, repr, fcx.llretptr.get().unwrap(), disr);
@ -2172,7 +2269,7 @@ pub fn trans_enum_variant_or_tuple_like_struct<A:IdAndTy>(
let arg_ty = arg_tys[i]; let arg_ty = arg_tys[i];
memcpy_ty(bcx, lldestptr, llarg, arg_ty); memcpy_ty(bcx, lldestptr, llarg, arg_ty);
} }
finish_fn(fcx, bcx); finish_fn(&fcx, bcx);
} }
pub fn trans_enum_def(ccx: @CrateContext, enum_definition: &ast::enum_def, pub fn trans_enum_def(ccx: @CrateContext, enum_definition: &ast::enum_def,
@ -2471,7 +2568,9 @@ pub fn create_entry_wrapper(ccx: @CrateContext,
} }
} }
pub fn fill_fn_pair(bcx: @Block, pair: ValueRef, llfn: ValueRef, pub fn fill_fn_pair(bcx: &Block,
pair: ValueRef,
llfn: ValueRef,
llenvptr: ValueRef) { llenvptr: ValueRef) {
let ccx = bcx.ccx(); let ccx = bcx.ccx();
let code_cell = GEPi(bcx, pair, [0u, abi::fn_field_code]); let code_cell = GEPi(bcx, pair, [0u, abi::fn_field_code]);
@ -2798,7 +2897,7 @@ pub fn register_method(ccx: @CrateContext,
llfn llfn
} }
pub fn vp2i(cx: @Block, v: ValueRef) -> ValueRef { pub fn vp2i(cx: &Block, v: ValueRef) -> ValueRef {
let ccx = cx.ccx(); let ccx = cx.ccx();
return PtrToInt(cx, v, ccx.int_type); return PtrToInt(cx, v, ccx.int_type);
} }
@ -2966,7 +3065,7 @@ pub fn declare_dbg_intrinsics(llmod: ModuleRef, intrinsics: &mut HashMap<&'stati
"llvm.dbg.value", [Type::metadata(), Type::i64(), Type::metadata()], Type::void()); "llvm.dbg.value", [Type::metadata(), Type::i64(), Type::metadata()], Type::void());
} }
pub fn trap(bcx: @Block) { pub fn trap(bcx: &Block) {
match bcx.ccx().intrinsics.find_equiv(& &"llvm.trap") { match bcx.ccx().intrinsics.find_equiv(& &"llvm.trap") {
Some(&x) => { Call(bcx, x, [], []); }, Some(&x) => { Call(bcx, x, [], []); },
_ => bcx.sess().bug("unbound llvm.trap in trap") _ => bcx.sess().bug("unbound llvm.trap in trap")

View File

@ -54,28 +54,30 @@ pub fn RetVoid(cx: &Block) {
B(cx).ret_void(); B(cx).ret_void();
} }
pub fn Ret(cx: @Block, V: ValueRef) { pub fn Ret(cx: &Block, V: ValueRef) {
if cx.unreachable.get() { return; } if cx.unreachable.get() { return; }
check_not_terminated(cx); check_not_terminated(cx);
terminate(cx, "Ret"); terminate(cx, "Ret");
B(cx).ret(V); B(cx).ret(V);
} }
pub fn AggregateRet(cx: @Block, RetVals: &[ValueRef]) { pub fn AggregateRet(cx: &Block, RetVals: &[ValueRef]) {
if cx.unreachable.get() { return; } if cx.unreachable.get() { return; }
check_not_terminated(cx); check_not_terminated(cx);
terminate(cx, "AggregateRet"); terminate(cx, "AggregateRet");
B(cx).aggregate_ret(RetVals); B(cx).aggregate_ret(RetVals);
} }
pub fn Br(cx: @Block, Dest: BasicBlockRef) { pub fn Br(cx: &Block, Dest: BasicBlockRef) {
if cx.unreachable.get() { return; } if cx.unreachable.get() { return; }
check_not_terminated(cx); check_not_terminated(cx);
terminate(cx, "Br"); terminate(cx, "Br");
B(cx).br(Dest); B(cx).br(Dest);
} }
pub fn CondBr(cx: @Block, If: ValueRef, Then: BasicBlockRef, pub fn CondBr(cx: &Block,
If: ValueRef,
Then: BasicBlockRef,
Else: BasicBlockRef) { Else: BasicBlockRef) {
if cx.unreachable.get() { return; } if cx.unreachable.get() { return; }
check_not_terminated(cx); check_not_terminated(cx);
@ -105,7 +107,7 @@ pub fn IndirectBr(cx: &Block, Addr: ValueRef, NumDests: uint) {
B(cx).indirect_br(Addr, NumDests); B(cx).indirect_br(Addr, NumDests);
} }
pub fn Invoke(cx: @Block, pub fn Invoke(cx: &Block,
Fn: ValueRef, Fn: ValueRef,
Args: &[ValueRef], Args: &[ValueRef],
Then: BasicBlockRef, Then: BasicBlockRef,
@ -762,7 +764,7 @@ pub fn SetCleanup(cx: &Block, LandingPad: ValueRef) {
B(cx).set_cleanup(LandingPad) B(cx).set_cleanup(LandingPad)
} }
pub fn Resume(cx: @Block, Exn: ValueRef) -> ValueRef { pub fn Resume(cx: &Block, Exn: ValueRef) -> ValueRef {
check_not_terminated(cx); check_not_terminated(cx);
terminate(cx, "Resume"); terminate(cx, "Resume");
B(cx).resume(Exn) B(cx).resume(Exn)

View File

@ -70,12 +70,12 @@ pub enum CalleeData {
Method(MethodData) Method(MethodData)
} }
pub struct Callee { pub struct Callee<'a> {
bcx: @Block, bcx: &'a Block<'a>,
data: CalleeData data: CalleeData
} }
pub fn trans(bcx: @Block, expr: &ast::Expr) -> Callee { pub fn trans<'a>(bcx: &'a Block<'a>, expr: &ast::Expr) -> Callee<'a> {
let _icx = push_ctxt("trans_callee"); let _icx = push_ctxt("trans_callee");
debug!("callee::trans(expr={})", expr.repr(bcx.tcx())); debug!("callee::trans(expr={})", expr.repr(bcx.tcx()));
@ -90,7 +90,7 @@ pub fn trans(bcx: @Block, expr: &ast::Expr) -> Callee {
// any other expressions are closures: // any other expressions are closures:
return datum_callee(bcx, expr); return datum_callee(bcx, expr);
fn datum_callee(bcx: @Block, expr: &ast::Expr) -> Callee { fn datum_callee<'a>(bcx: &'a Block<'a>, expr: &ast::Expr) -> Callee<'a> {
let DatumBlock {bcx, datum} = expr::trans_to_datum(bcx, expr); let DatumBlock {bcx, datum} = expr::trans_to_datum(bcx, expr);
match ty::get(datum.ty).sty { match ty::get(datum.ty).sty {
ty::ty_bare_fn(..) => { ty::ty_bare_fn(..) => {
@ -109,11 +109,12 @@ pub fn trans(bcx: @Block, expr: &ast::Expr) -> Callee {
} }
} }
fn fn_callee(bcx: @Block, fd: FnData) -> Callee { fn fn_callee<'a>(bcx: &'a Block<'a>, fd: FnData) -> Callee<'a> {
return Callee {bcx: bcx, data: Fn(fd)}; return Callee {bcx: bcx, data: Fn(fd)};
} }
fn trans_def(bcx: @Block, def: ast::Def, ref_expr: &ast::Expr) -> Callee { fn trans_def<'a>(bcx: &'a Block<'a>, def: ast::Def, ref_expr: &ast::Expr)
-> Callee<'a> {
match def { match def {
ast::DefFn(did, _) | ast::DefFn(did, _) |
ast::DefStaticMethod(did, ast::FromImpl(_), _) => { ast::DefStaticMethod(did, ast::FromImpl(_), _) => {
@ -158,16 +159,17 @@ pub fn trans(bcx: @Block, expr: &ast::Expr) -> Callee {
} }
} }
pub fn trans_fn_ref_to_callee(bcx: @Block, pub fn trans_fn_ref_to_callee<'a>(
bcx: &'a Block<'a>,
def_id: ast::DefId, def_id: ast::DefId,
ref_id: ast::NodeId) -> Callee { ref_id: ast::NodeId)
-> Callee<'a> {
Callee {bcx: bcx, Callee {bcx: bcx,
data: Fn(trans_fn_ref(bcx, def_id, ref_id))} data: Fn(trans_fn_ref(bcx, def_id, ref_id))}
} }
pub fn trans_fn_ref(bcx: @Block, pub fn trans_fn_ref(bcx: &Block, def_id: ast::DefId, ref_id: ast::NodeId)
def_id: ast::DefId, -> FnData {
ref_id: ast::NodeId) -> FnData {
/*! /*!
* *
* Translates a reference (with id `ref_id`) to the fn/method * Translates a reference (with id `ref_id`) to the fn/method
@ -184,19 +186,19 @@ pub fn trans_fn_ref(bcx: @Block,
trans_fn_ref_with_vtables(bcx, def_id, ref_id, type_params, vtables) trans_fn_ref_with_vtables(bcx, def_id, ref_id, type_params, vtables)
} }
pub fn trans_fn_ref_with_vtables_to_callee( pub fn trans_fn_ref_with_vtables_to_callee<'a>(
bcx: @Block, bcx: &'a Block<'a>,
def_id: ast::DefId, def_id: ast::DefId,
ref_id: ast::NodeId, ref_id: ast::NodeId,
type_params: &[ty::t], type_params: &[ty::t],
vtables: Option<typeck::vtable_res>) vtables: Option<typeck::vtable_res>)
-> Callee { -> Callee<'a> {
Callee {bcx: bcx, Callee {bcx: bcx,
data: Fn(trans_fn_ref_with_vtables(bcx, def_id, ref_id, data: Fn(trans_fn_ref_with_vtables(bcx, def_id, ref_id,
type_params, vtables))} type_params, vtables))}
} }
fn resolve_default_method_vtables(bcx: @Block, fn resolve_default_method_vtables(bcx: &Block,
impl_id: ast::DefId, impl_id: ast::DefId,
method: &ty::Method, method: &ty::Method,
substs: &ty::substs, substs: &ty::substs,
@ -239,7 +241,7 @@ fn resolve_default_method_vtables(bcx: @Block,
pub fn trans_fn_ref_with_vtables( pub fn trans_fn_ref_with_vtables(
bcx: @Block, // bcx: &Block, //
def_id: ast::DefId, // def id of fn def_id: ast::DefId, // def id of fn
ref_id: ast::NodeId, // node id of use of fn; may be zero if N/A ref_id: ast::NodeId, // node id of use of fn; may be zero if N/A
type_params: &[ty::t], // values for fn's ty params type_params: &[ty::t], // values for fn's ty params
@ -447,13 +449,14 @@ pub fn trans_fn_ref_with_vtables(
// ______________________________________________________________________ // ______________________________________________________________________
// Translating calls // Translating calls
pub fn trans_call(in_cx: @Block, pub fn trans_call<'a>(
in_cx: &'a Block<'a>,
call_ex: &ast::Expr, call_ex: &ast::Expr,
f: &ast::Expr, f: &ast::Expr,
args: CallArgs, args: CallArgs,
id: ast::NodeId, id: ast::NodeId,
dest: expr::Dest) dest: expr::Dest)
-> @Block { -> &'a Block<'a> {
let _icx = push_ctxt("trans_call"); let _icx = push_ctxt("trans_call");
trans_call_inner(in_cx, trans_call_inner(in_cx,
call_ex.info(), call_ex.info(),
@ -465,13 +468,14 @@ pub fn trans_call(in_cx: @Block,
DontAutorefArg).bcx DontAutorefArg).bcx
} }
pub fn trans_method_call(in_cx: @Block, pub fn trans_method_call<'a>(
in_cx: &'a Block<'a>,
call_ex: &ast::Expr, call_ex: &ast::Expr,
callee_id: ast::NodeId, callee_id: ast::NodeId,
rcvr: &ast::Expr, rcvr: &ast::Expr,
args: CallArgs, args: CallArgs,
dest: expr::Dest) dest: expr::Dest)
-> @Block { -> &'a Block<'a> {
let _icx = push_ctxt("trans_method_call"); let _icx = push_ctxt("trans_method_call");
debug!("trans_method_call(call_ex={}, rcvr={})", debug!("trans_method_call(call_ex={}, rcvr={})",
call_ex.repr(in_cx.tcx()), call_ex.repr(in_cx.tcx()),
@ -507,11 +511,12 @@ pub fn trans_method_call(in_cx: @Block,
DontAutorefArg).bcx DontAutorefArg).bcx
} }
pub fn trans_lang_call(bcx: @Block, pub fn trans_lang_call<'a>(
bcx: &'a Block<'a>,
did: ast::DefId, did: ast::DefId,
args: &[ValueRef], args: &[ValueRef],
dest: Option<expr::Dest>) dest: Option<expr::Dest>)
-> Result { -> Result<'a> {
let fty = if did.crate == ast::LOCAL_CRATE { let fty = if did.crate == ast::LOCAL_CRATE {
ty::node_id_to_type(bcx.ccx().tcx, did.node) ty::node_id_to_type(bcx.ccx().tcx, did.node)
} else { } else {
@ -534,12 +539,13 @@ pub fn trans_lang_call(bcx: @Block,
DontAutorefArg) DontAutorefArg)
} }
pub fn trans_lang_call_with_type_params(bcx: @Block, pub fn trans_lang_call_with_type_params<'a>(
bcx: &'a Block<'a>,
did: ast::DefId, did: ast::DefId,
args: &[ValueRef], args: &[ValueRef],
type_params: &[ty::t], type_params: &[ty::t],
dest: expr::Dest) dest: expr::Dest)
-> @Block { -> &'a Block<'a> {
let fty; let fty;
if did.crate == ast::LOCAL_CRATE { if did.crate == ast::LOCAL_CRATE {
fty = ty::node_id_to_type(bcx.tcx(), did.node); fty = ty::node_id_to_type(bcx.tcx(), did.node);
@ -574,15 +580,16 @@ pub fn trans_lang_call_with_type_params(bcx: @Block,
ArgVals(args), Some(dest), DontAutorefArg).bcx; ArgVals(args), Some(dest), DontAutorefArg).bcx;
} }
pub fn trans_call_inner(in_cx: @Block, pub fn trans_call_inner<'a>(
in_cx: &'a Block<'a>,
call_info: Option<NodeInfo>, call_info: Option<NodeInfo>,
callee_ty: ty::t, callee_ty: ty::t,
ret_ty: ty::t, ret_ty: ty::t,
get_callee: |@Block| -> Callee, get_callee: |&'a Block<'a>| -> Callee<'a>,
args: CallArgs, args: CallArgs,
dest: Option<expr::Dest>, dest: Option<expr::Dest>,
autoref_arg: AutorefArg) autoref_arg: AutorefArg)
-> Result { -> Result<'a> {
/*! /*!
* This behemoth of a function translates function calls. * This behemoth of a function translates function calls.
* Unfortunately, in order to generate more efficient LLVM * Unfortunately, in order to generate more efficient LLVM
@ -762,12 +769,13 @@ pub enum CallArgs<'a> {
ArgVals(&'a [ValueRef]) ArgVals(&'a [ValueRef])
} }
pub fn trans_args(cx: @Block, pub fn trans_args<'a>(
cx: &'a Block<'a>,
args: CallArgs, args: CallArgs,
fn_ty: ty::t, fn_ty: ty::t,
autoref_arg: AutorefArg, autoref_arg: AutorefArg,
llargs: &mut ~[ValueRef]) -> @Block llargs: &mut ~[ValueRef])
{ -> &'a Block<'a> {
let _icx = push_ctxt("trans_args"); let _icx = push_ctxt("trans_args");
let mut temp_cleanups = ~[]; let mut temp_cleanups = ~[];
let arg_tys = ty::ty_fn_args(fn_ty); let arg_tys = ty::ty_fn_args(fn_ty);
@ -821,12 +829,14 @@ pub enum AutorefArg {
// temp_cleanups: cleanups that should run only if failure occurs before the // temp_cleanups: cleanups that should run only if failure occurs before the
// call takes place: // call takes place:
pub fn trans_arg_expr(bcx: @Block, pub fn trans_arg_expr<'a>(
bcx: &'a Block<'a>,
formal_arg_ty: ty::t, formal_arg_ty: ty::t,
self_mode: ty::SelfMode, self_mode: ty::SelfMode,
arg_expr: &ast::Expr, arg_expr: &ast::Expr,
temp_cleanups: &mut ~[ValueRef], temp_cleanups: &mut ~[ValueRef],
autoref_arg: AutorefArg) -> Result { autoref_arg: AutorefArg)
-> Result<'a> {
let _icx = push_ctxt("trans_arg_expr"); let _icx = push_ctxt("trans_arg_expr");
let ccx = bcx.ccx(); let ccx = bcx.ccx();

View File

@ -155,7 +155,7 @@ pub fn mk_closure_tys(tcx: ty::ctxt,
return cdata_ty; return cdata_ty;
} }
fn heap_for_unique_closure(bcx: @Block, t: ty::t) -> heap { fn heap_for_unique_closure(bcx: &Block, t: ty::t) -> heap {
if ty::type_contents(bcx.tcx(), t).owns_managed() { if ty::type_contents(bcx.tcx(), t).owns_managed() {
heap_managed_unique heap_managed_unique
} else { } else {
@ -163,8 +163,11 @@ fn heap_for_unique_closure(bcx: @Block, t: ty::t) -> heap {
} }
} }
pub fn allocate_cbox(bcx: @Block, sigil: ast::Sigil, cdata_ty: ty::t) pub fn allocate_cbox<'a>(
-> Result { bcx: &'a Block<'a>,
sigil: ast::Sigil,
cdata_ty: ty::t)
-> Result<'a> {
let _icx = push_ctxt("closure::allocate_cbox"); let _icx = push_ctxt("closure::allocate_cbox");
let ccx = bcx.ccx(); let ccx = bcx.ccx();
let tcx = ccx.tcx; let tcx = ccx.tcx;
@ -185,20 +188,21 @@ pub fn allocate_cbox(bcx: @Block, sigil: ast::Sigil, cdata_ty: ty::t)
} }
} }
pub struct ClosureResult { pub struct ClosureResult<'a> {
llbox: ValueRef, // llvalue of ptr to closure llbox: ValueRef, // llvalue of ptr to closure
cdata_ty: ty::t, // type of the closure data cdata_ty: ty::t, // type of the closure data
bcx: @Block // final bcx bcx: &'a Block<'a> // final bcx
} }
// Given a block context and a list of tydescs and values to bind // Given a block context and a list of tydescs and values to bind
// construct a closure out of them. If copying is true, it is a // construct a closure out of them. If copying is true, it is a
// heap allocated closure that copies the upvars into environment. // heap allocated closure that copies the upvars into environment.
// Otherwise, it is stack allocated and copies pointers to the upvars. // Otherwise, it is stack allocated and copies pointers to the upvars.
pub fn store_environment(bcx: @Block, pub fn store_environment<'a>(
bcx: &'a Block<'a>,
bound_values: ~[EnvValue], bound_values: ~[EnvValue],
sigil: ast::Sigil) sigil: ast::Sigil)
-> ClosureResult { -> ClosureResult<'a> {
let _icx = push_ctxt("closure::store_environment"); let _icx = push_ctxt("closure::store_environment");
let ccx = bcx.ccx(); let ccx = bcx.ccx();
let tcx = ccx.tcx; let tcx = ccx.tcx;
@ -257,9 +261,11 @@ pub fn store_environment(bcx: @Block,
// Given a context and a list of upvars, build a closure. This just // Given a context and a list of upvars, build a closure. This just
// collects the upvars and packages them up for store_environment. // collects the upvars and packages them up for store_environment.
pub fn build_closure(bcx0: @Block, pub fn build_closure<'a>(
bcx0: &'a Block<'a>,
cap_vars: &[moves::CaptureVar], cap_vars: &[moves::CaptureVar],
sigil: ast::Sigil) -> ClosureResult { sigil: ast::Sigil)
-> ClosureResult<'a> {
let _icx = push_ctxt("closure::build_closure"); let _icx = push_ctxt("closure::build_closure");
// If we need to, package up the iterator body to call // If we need to, package up the iterator body to call
@ -293,7 +299,7 @@ pub fn build_closure(bcx0: @Block,
// Given an enclosing block context, a new function context, a closure type, // Given an enclosing block context, a new function context, a closure type,
// and a list of upvars, generate code to load and populate the environment // and a list of upvars, generate code to load and populate the environment
// with the upvars and type descriptors. // with the upvars and type descriptors.
pub fn load_environment(fcx: @FunctionContext, pub fn load_environment(fcx: &FunctionContext,
cdata_ty: ty::t, cdata_ty: ty::t,
cap_vars: &[moves::CaptureVar], cap_vars: &[moves::CaptureVar],
sigil: ast::Sigil) { sigil: ast::Sigil) {
@ -349,13 +355,15 @@ pub fn load_environment(fcx: @FunctionContext,
} }
} }
pub fn trans_expr_fn(bcx: @Block, pub fn trans_expr_fn<'a>(
bcx: &'a Block<'a>,
sigil: ast::Sigil, sigil: ast::Sigil,
decl: &ast::fn_decl, decl: &ast::fn_decl,
body: &ast::Block, body: &ast::Block,
outer_id: ast::NodeId, outer_id: ast::NodeId,
user_id: ast::NodeId, user_id: ast::NodeId,
dest: expr::Dest) -> @Block { dest: expr::Dest)
-> &'a Block<'a> {
/*! /*!
* *
* Translates the body of a closure expression. * Translates the body of a closure expression.
@ -429,12 +437,13 @@ pub fn trans_expr_fn(bcx: @Block,
return bcx; return bcx;
} }
pub fn make_closure_glue(cx: @Block, pub fn make_closure_glue<'a>(
cx: &'a Block<'a>,
v: ValueRef, v: ValueRef,
t: ty::t, t: ty::t,
glue_fn: |@Block, v: ValueRef, t: ty::t| glue_fn: |&'a Block<'a>, v: ValueRef, t: ty::t|
-> @Block) -> &'a Block<'a>)
-> @Block { -> &'a Block<'a> {
let _icx = push_ctxt("closure::make_closure_glue"); let _icx = push_ctxt("closure::make_closure_glue");
let bcx = cx; let bcx = cx;
let tcx = cx.tcx(); let tcx = cx.tcx();
@ -453,11 +462,11 @@ pub fn make_closure_glue(cx: @Block,
} }
} }
pub fn make_opaque_cbox_drop_glue( pub fn make_opaque_cbox_drop_glue<'a>(
bcx: @Block, bcx: &'a Block<'a>,
sigil: ast::Sigil, sigil: ast::Sigil,
cboxptr: ValueRef) // ptr to the opaque closure cboxptr: ValueRef) // opaque closure ptr
-> @Block { -> &'a Block<'a> {
let _icx = push_ctxt("closure::make_opaque_cbox_drop_glue"); let _icx = push_ctxt("closure::make_opaque_cbox_drop_glue");
match sigil { match sigil {
ast::BorrowedSigil => bcx, ast::BorrowedSigil => bcx,
@ -473,10 +482,11 @@ pub fn make_opaque_cbox_drop_glue(
} }
/// `cbox` is a pointer to a pointer to an opaque closure. /// `cbox` is a pointer to a pointer to an opaque closure.
pub fn make_opaque_cbox_free_glue(bcx: @Block, pub fn make_opaque_cbox_free_glue<'a>(
bcx: &'a Block<'a>,
sigil: ast::Sigil, sigil: ast::Sigil,
cbox: ValueRef) cbox: ValueRef)
-> @Block { -> &'a Block<'a> {
let _icx = push_ctxt("closure::make_opaque_cbox_free_glue"); let _icx = push_ctxt("closure::make_opaque_cbox_free_glue");
match sigil { match sigil {
ast::BorrowedSigil => { ast::BorrowedSigil => {

View File

@ -23,13 +23,14 @@ use middle::trans::build;
use middle::trans::datum; use middle::trans::datum;
use middle::trans::glue; use middle::trans::glue;
use middle::trans::debuginfo; use middle::trans::debuginfo;
use middle::trans::type_::Type;
use middle::ty::substs; use middle::ty::substs;
use middle::ty; use middle::ty;
use middle::typeck; use middle::typeck;
use util::ppaux::Repr; use util::ppaux::Repr;
use middle::trans::type_::Type;
use extra::arena::TypedArena;
use std::c_str::ToCStr; use std::c_str::ToCStr;
use std::cast::transmute; use std::cast::transmute;
use std::cast; use std::cast;
@ -195,7 +196,7 @@ impl Repr for param_substs {
// Function context. Every LLVM function we create will have one of // Function context. Every LLVM function we create will have one of
// these. // these.
pub struct FunctionContext { pub struct FunctionContext<'a> {
// The ValueRef returned from a call to llvm::LLVMAddFunction; the // The ValueRef returned from a call to llvm::LLVMAddFunction; the
// address of the first instruction in the sequence of // address of the first instruction in the sequence of
// instructions for this function that will go in the .text // instructions for this function that will go in the .text
@ -212,7 +213,7 @@ pub struct FunctionContext {
// always be Some. // always be Some.
llretptr: Cell<Option<ValueRef>>, llretptr: Cell<Option<ValueRef>>,
entry_bcx: RefCell<Option<@Block>>, entry_bcx: RefCell<Option<&'a Block<'a>>>,
// These elements: "hoisted basic blocks" containing // These elements: "hoisted basic blocks" containing
// administrative activities that have to happen in only one place in // administrative activities that have to happen in only one place in
@ -258,6 +259,12 @@ pub struct FunctionContext {
span: Option<Span>, span: Option<Span>,
path: path, path: path,
// The arena that blocks are allocated from.
block_arena: TypedArena<Block<'a>>,
// The arena that scope info is allocated from.
scope_info_arena: TypedArena<ScopeInfo<'a>>,
// This function's enclosing crate context. // This function's enclosing crate context.
ccx: @CrateContext, ccx: @CrateContext,
@ -265,7 +272,7 @@ pub struct FunctionContext {
debug_context: debuginfo::FunctionDebugContext, debug_context: debuginfo::FunctionDebugContext,
} }
impl FunctionContext { impl<'a> FunctionContext<'a> {
pub fn arg_pos(&self, arg: uint) -> uint { pub fn arg_pos(&self, arg: uint) -> uint {
if self.caller_expects_out_pointer { if self.caller_expects_out_pointer {
arg + 2u arg + 2u
@ -332,7 +339,7 @@ pub enum cleantype {
/// A cleanup function: a built-in destructor. /// A cleanup function: a built-in destructor.
pub trait CleanupFunction { pub trait CleanupFunction {
fn clean(&self, block: @Block) -> @Block; fn clean<'a>(&self, block: &'a Block<'a>) -> &'a Block<'a>;
} }
/// A cleanup function that calls the "drop glue" (destructor function) on /// A cleanup function that calls the "drop glue" (destructor function) on
@ -343,7 +350,7 @@ pub struct TypeDroppingCleanupFunction {
} }
impl CleanupFunction for TypeDroppingCleanupFunction { impl CleanupFunction for TypeDroppingCleanupFunction {
fn clean(&self, block: @Block) -> @Block { fn clean<'a>(&self, block: &'a Block<'a>) -> &'a Block<'a> {
glue::drop_ty(block, self.val, self.t) glue::drop_ty(block, self.val, self.t)
} }
} }
@ -356,7 +363,7 @@ pub struct ImmediateTypeDroppingCleanupFunction {
} }
impl CleanupFunction for ImmediateTypeDroppingCleanupFunction { impl CleanupFunction for ImmediateTypeDroppingCleanupFunction {
fn clean(&self, block: @Block) -> @Block { fn clean<'a>(&self, block: &'a Block<'a>) -> &'a Block<'a> {
glue::drop_ty_immediate(block, self.val, self.t) glue::drop_ty_immediate(block, self.val, self.t)
} }
} }
@ -367,7 +374,7 @@ pub struct GCHeapFreeingCleanupFunction {
} }
impl CleanupFunction for GCHeapFreeingCleanupFunction { impl CleanupFunction for GCHeapFreeingCleanupFunction {
fn clean(&self, bcx: @Block) -> @Block { fn clean<'a>(&self, bcx: &'a Block<'a>) -> &'a Block<'a> {
glue::trans_free(bcx, self.ptr) glue::trans_free(bcx, self.ptr)
} }
} }
@ -378,7 +385,7 @@ pub struct ExchangeHeapFreeingCleanupFunction {
} }
impl CleanupFunction for ExchangeHeapFreeingCleanupFunction { impl CleanupFunction for ExchangeHeapFreeingCleanupFunction {
fn clean(&self, bcx: @Block) -> @Block { fn clean<'a>(&self, bcx: &'a Block) -> &'a Block<'a> {
glue::trans_exchange_free(bcx, self.ptr) glue::trans_exchange_free(bcx, self.ptr)
} }
} }
@ -432,7 +439,7 @@ pub fn cleanup_type(cx: ty::ctxt, ty: ty::t) -> cleantype {
} }
} }
pub fn add_clean(bcx: @Block, val: ValueRef, t: ty::t) { pub fn add_clean(bcx: &Block, val: ValueRef, t: ty::t) {
if !ty::type_needs_drop(bcx.tcx(), t) { if !ty::type_needs_drop(bcx.tcx(), t) {
return return
} }
@ -453,7 +460,7 @@ pub fn add_clean(bcx: @Block, val: ValueRef, t: ty::t) {
}) })
} }
pub fn add_clean_temp_immediate(cx: @Block, val: ValueRef, ty: ty::t) { pub fn add_clean_temp_immediate(cx: &Block, val: ValueRef, ty: ty::t) {
if !ty::type_needs_drop(cx.tcx(), ty) { return; } if !ty::type_needs_drop(cx.tcx(), ty) { return; }
debug!("add_clean_temp_immediate({}, {}, {})", debug!("add_clean_temp_immediate({}, {}, {})",
cx.to_str(), cx.val_to_str(val), cx.to_str(), cx.val_to_str(val),
@ -473,18 +480,18 @@ pub fn add_clean_temp_immediate(cx: @Block, val: ValueRef, ty: ty::t) {
}) })
} }
pub fn add_clean_temp_mem(bcx: @Block, val: ValueRef, t: ty::t) { pub fn add_clean_temp_mem(bcx: &Block, val: ValueRef, t: ty::t) {
add_clean_temp_mem_in_scope_(bcx, None, val, t); add_clean_temp_mem_in_scope_(bcx, None, val, t);
} }
pub fn add_clean_temp_mem_in_scope(bcx: @Block, pub fn add_clean_temp_mem_in_scope(bcx: &Block,
scope_id: ast::NodeId, scope_id: ast::NodeId,
val: ValueRef, val: ValueRef,
t: ty::t) { t: ty::t) {
add_clean_temp_mem_in_scope_(bcx, Some(scope_id), val, t); add_clean_temp_mem_in_scope_(bcx, Some(scope_id), val, t);
} }
pub fn add_clean_temp_mem_in_scope_(bcx: @Block, scope_id: Option<ast::NodeId>, pub fn add_clean_temp_mem_in_scope_(bcx: &Block, scope_id: Option<ast::NodeId>,
val: ValueRef, t: ty::t) { val: ValueRef, t: ty::t) {
if !ty::type_needs_drop(bcx.tcx(), t) { return; } if !ty::type_needs_drop(bcx.tcx(), t) { return; }
debug!("add_clean_temp_mem({}, {}, {})", debug!("add_clean_temp_mem({}, {}, {})",
@ -505,7 +512,7 @@ pub fn add_clean_temp_mem_in_scope_(bcx: @Block, scope_id: Option<ast::NodeId>,
}) })
} }
pub fn add_clean_free(cx: @Block, ptr: ValueRef, heap: heap) { pub fn add_clean_free(cx: &Block, ptr: ValueRef, heap: heap) {
let free_fn = match heap { let free_fn = match heap {
heap_managed | heap_managed_unique => { heap_managed | heap_managed_unique => {
@GCHeapFreeingCleanupFunction { @GCHeapFreeingCleanupFunction {
@ -533,7 +540,7 @@ pub fn add_clean_free(cx: @Block, ptr: ValueRef, heap: heap) {
// to a system where we can also cancel the cleanup on local variables, but // to a system where we can also cancel the cleanup on local variables, but
// this will be more involved. For now, we simply zero out the local, and the // this will be more involved. For now, we simply zero out the local, and the
// drop glue checks whether it is zero. // drop glue checks whether it is zero.
pub fn revoke_clean(cx: @Block, val: ValueRef) { pub fn revoke_clean(cx: &Block, val: ValueRef) {
in_scope_cx(cx, None, |scope_info| { in_scope_cx(cx, None, |scope_info| {
let cleanup_pos = { let cleanup_pos = {
let mut cleanups = scope_info.cleanups.borrow_mut(); let mut cleanups = scope_info.cleanups.borrow_mut();
@ -564,9 +571,9 @@ pub fn block_cleanups(bcx: &Block) -> ~[cleanup] {
} }
} }
pub struct ScopeInfo { pub struct ScopeInfo<'a> {
parent: Option<@ScopeInfo>, parent: Option<&'a ScopeInfo<'a>>,
loop_break: Option<@Block>, loop_break: Option<&'a Block<'a>>,
loop_label: Option<Name>, loop_label: Option<Name>,
// A list of functions that must be run at when leaving this // A list of functions that must be run at when leaving this
// block, cleaning up any variables that were introduced in the // block, cleaning up any variables that were introduced in the
@ -581,7 +588,7 @@ pub struct ScopeInfo {
node_info: Option<NodeInfo>, node_info: Option<NodeInfo>,
} }
impl ScopeInfo { impl<'a> ScopeInfo<'a> {
pub fn empty_cleanups(&self) -> bool { pub fn empty_cleanups(&self) -> bool {
let cleanups = self.cleanups.borrow(); let cleanups = self.cleanups.borrow();
cleanups.get().is_empty() cleanups.get().is_empty()
@ -625,7 +632,7 @@ pub struct NodeInfo {
// code. Each basic block we generate is attached to a function, typically // code. Each basic block we generate is attached to a function, typically
// with many basic blocks per function. All the basic blocks attached to a // with many basic blocks per function. All the basic blocks attached to a
// function are organized as a directed graph. // function are organized as a directed graph.
pub struct Block { pub struct Block<'a> {
// The BasicBlockRef returned from a call to // The BasicBlockRef returned from a call to
// llvm::LLVMAppendBasicBlock(llfn, name), which adds a basic // llvm::LLVMAppendBasicBlock(llfn, name), which adds a basic
// block to the function pointed to by llfn. We insert // block to the function pointed to by llfn. We insert
@ -634,26 +641,27 @@ pub struct Block {
llbb: BasicBlockRef, llbb: BasicBlockRef,
terminated: Cell<bool>, terminated: Cell<bool>,
unreachable: Cell<bool>, unreachable: Cell<bool>,
parent: Option<@Block>, parent: Option<&'a Block<'a>>,
// The current scope within this basic block // The current scope within this basic block
scope: RefCell<Option<@ScopeInfo>>, scope: RefCell<Option<&'a ScopeInfo<'a>>>,
// Is this block part of a landing pad? // Is this block part of a landing pad?
is_lpad: bool, is_lpad: bool,
// info about the AST node this block originated from, if any // info about the AST node this block originated from, if any
node_info: Option<NodeInfo>, node_info: Option<NodeInfo>,
// The function context for the function to which this block is // The function context for the function to which this block is
// attached. // attached.
fcx: @FunctionContext fcx: &'a FunctionContext<'a>,
} }
impl Block { impl<'a> Block<'a> {
pub fn new(llbb: BasicBlockRef, pub fn new<'a>(
parent: Option<@Block>, llbb: BasicBlockRef,
parent: Option<&'a Block<'a>>,
is_lpad: bool, is_lpad: bool,
node_info: Option<NodeInfo>, node_info: Option<NodeInfo>,
fcx: @FunctionContext) fcx: &'a FunctionContext<'a>)
-> Block { -> &'a Block<'a> {
Block { fcx.block_arena.alloc(Block {
llbb: llbb, llbb: llbb,
terminated: Cell::new(false), terminated: Cell::new(false),
unreachable: Cell::new(false), unreachable: Cell::new(false),
@ -661,12 +669,14 @@ impl Block {
scope: RefCell::new(None), scope: RefCell::new(None),
is_lpad: is_lpad, is_lpad: is_lpad,
node_info: node_info, node_info: node_info,
fcx: fcx fcx: fcx,
} })
} }
pub fn ccx(&self) -> @CrateContext { self.fcx.ccx } pub fn ccx(&self) -> @CrateContext { self.fcx.ccx }
pub fn tcx(&self) -> ty::ctxt { self.fcx.ccx.tcx } pub fn tcx(&self) -> ty::ctxt {
self.fcx.ccx.tcx
}
pub fn sess(&self) -> Session { self.fcx.ccx.sess } pub fn sess(&self) -> Session { self.fcx.ccx.sess }
pub fn ident(&self, ident: Ident) -> @str { pub fn ident(&self, ident: Ident) -> @str {
@ -722,17 +732,20 @@ impl Block {
} }
} }
pub struct Result { pub struct Result<'a> {
bcx: @Block, bcx: &'a Block<'a>,
val: ValueRef val: ValueRef
} }
pub fn rslt(bcx: @Block, val: ValueRef) -> Result { pub fn rslt<'a>(bcx: &'a Block<'a>, val: ValueRef) -> Result<'a> {
Result {bcx: bcx, val: val} Result {
bcx: bcx,
val: val,
}
} }
impl Result { impl<'a> Result<'a> {
pub fn unpack(&self, bcx: &mut @Block) -> ValueRef { pub fn unpack(&self, bcx: &mut &'a Block<'a>) -> ValueRef {
*bcx = self.bcx; *bcx = self.bcx;
return self.val; return self.val;
} }
@ -744,9 +757,10 @@ pub fn val_ty(v: ValueRef) -> Type {
} }
} }
pub fn in_scope_cx(cx: @Block, pub fn in_scope_cx<'a>(
cx: &'a Block<'a>,
scope_id: Option<ast::NodeId>, scope_id: Option<ast::NodeId>,
f: |si: &ScopeInfo|) { f: |si: &'a ScopeInfo<'a>|) {
let mut cur = cx; let mut cur = cx;
let mut cur_scope = cur.scope.get(); let mut cur_scope = cur.scope.get();
loop { loop {
@ -776,7 +790,7 @@ pub fn in_scope_cx(cx: @Block,
} }
} }
pub fn block_parent(cx: @Block) -> @Block { pub fn block_parent<'a>(cx: &'a Block<'a>) -> &'a Block<'a> {
match cx.parent { match cx.parent {
Some(b) => b, Some(b) => b,
None => cx.sess().bug(format!("block_parent called on root block {:?}", None => cx.sess().bug(format!("block_parent called on root block {:?}",
@ -1048,17 +1062,17 @@ pub struct mono_id_ {
pub type mono_id = @mono_id_; pub type mono_id = @mono_id_;
pub fn umax(cx: @Block, a: ValueRef, b: ValueRef) -> ValueRef { pub fn umax(cx: &Block, a: ValueRef, b: ValueRef) -> ValueRef {
let cond = build::ICmp(cx, lib::llvm::IntULT, a, b); let cond = build::ICmp(cx, lib::llvm::IntULT, a, b);
return build::Select(cx, cond, b, a); return build::Select(cx, cond, b, a);
} }
pub fn umin(cx: @Block, a: ValueRef, b: ValueRef) -> ValueRef { pub fn umin(cx: &Block, a: ValueRef, b: ValueRef) -> ValueRef {
let cond = build::ICmp(cx, lib::llvm::IntULT, a, b); let cond = build::ICmp(cx, lib::llvm::IntULT, a, b);
return build::Select(cx, cond, a, b); return build::Select(cx, cond, a, b);
} }
pub fn align_to(cx: @Block, off: ValueRef, align: ValueRef) -> ValueRef { pub fn align_to(cx: &Block, off: ValueRef, align: ValueRef) -> ValueRef {
let mask = build::Sub(cx, align, C_int(cx.ccx(), 1)); let mask = build::Sub(cx, align, C_int(cx.ccx(), 1));
let bumped = build::Add(cx, off, mask); let bumped = build::Add(cx, off, mask);
return build::And(cx, bumped, build::Not(cx, mask)); return build::And(cx, bumped, build::Not(cx, mask));
@ -1132,7 +1146,7 @@ pub fn node_id_type_params(bcx: &Block, id: ast::NodeId) -> ~[ty::t] {
} }
} }
pub fn node_vtables(bcx: @Block, id: ast::NodeId) pub fn node_vtables(bcx: &Block, id: ast::NodeId)
-> Option<typeck::vtable_res> { -> Option<typeck::vtable_res> {
let vtable_map = bcx.ccx().maps.vtable_map.borrow(); let vtable_map = bcx.ccx().maps.vtable_map.borrow();
let raw_vtables = vtable_map.get().find(&id); let raw_vtables = vtable_map.get().find(&id);
@ -1233,8 +1247,8 @@ pub fn dummy_substs(tps: ~[ty::t]) -> ty::substs {
} }
} }
pub fn filename_and_line_num_from_span(bcx: @Block, pub fn filename_and_line_num_from_span(bcx: &Block, span: Span)
span: Span) -> (ValueRef, ValueRef) { -> (ValueRef, ValueRef) {
let loc = bcx.sess().parse_sess.cm.lookup_char_pos(span.lo); let loc = bcx.sess().parse_sess.cm.lookup_char_pos(span.lo);
let filename_cstr = C_cstr(bcx.ccx(), loc.file.name); let filename_cstr = C_cstr(bcx.ccx(), loc.file.name);
let filename = build::PointerCast(bcx, filename_cstr, Type::i8p()); let filename = build::PointerCast(bcx, filename_cstr, Type::i8p());
@ -1243,12 +1257,15 @@ pub fn filename_and_line_num_from_span(bcx: @Block,
} }
// Casts a Rust bool value to an i1. // Casts a Rust bool value to an i1.
pub fn bool_to_i1(bcx: @Block, llval: ValueRef) -> ValueRef { pub fn bool_to_i1(bcx: &Block, llval: ValueRef) -> ValueRef {
build::ICmp(bcx, lib::llvm::IntNE, llval, C_bool(false)) build::ICmp(bcx, lib::llvm::IntNE, llval, C_bool(false))
} }
pub fn langcall(bcx: @Block, span: Option<Span>, msg: &str, pub fn langcall(bcx: &Block,
li: LangItem) -> ast::DefId { span: Option<Span>,
msg: &str,
li: LangItem)
-> ast::DefId {
match bcx.tcx().lang_items.require(li) { match bcx.tcx().lang_items.require(li) {
Ok(id) => id, Ok(id) => id,
Err(s) => { Err(s) => {

View File

@ -28,7 +28,8 @@ use syntax::ast_util;
use syntax::codemap::Span; use syntax::codemap::Span;
use syntax::visit::Visitor; use syntax::visit::Visitor;
pub fn trans_block(bcx: @Block, b: &ast::Block, dest: expr::Dest) -> @Block { pub fn trans_block<'a>(bcx: &'a Block<'a>, b: &ast::Block, dest: expr::Dest)
-> &'a Block<'a> {
let _icx = push_ctxt("trans_block"); let _icx = push_ctxt("trans_block");
let mut bcx = bcx; let mut bcx = bcx;
for s in b.stmts.iter() { for s in b.stmts.iter() {
@ -45,12 +46,13 @@ pub fn trans_block(bcx: @Block, b: &ast::Block, dest: expr::Dest) -> @Block {
return bcx; return bcx;
} }
pub fn trans_if(bcx: @Block, pub fn trans_if<'a>(
bcx: &'a Block<'a>,
cond: &ast::Expr, cond: &ast::Expr,
thn: ast::P<ast::Block>, thn: ast::P<ast::Block>,
els: Option<@ast::Expr>, els: Option<@ast::Expr>,
dest: expr::Dest) dest: expr::Dest)
-> @Block { -> &'a Block<'a> {
debug!("trans_if(bcx={}, cond={}, thn={:?}, dest={})", debug!("trans_if(bcx={}, cond={}, thn={:?}, dest={})",
bcx.to_str(), bcx.expr_to_str(cond), thn.id, bcx.to_str(), bcx.expr_to_str(cond), thn.id,
dest.to_str(bcx.ccx())); dest.to_str(bcx.ccx()));
@ -137,8 +139,12 @@ pub fn trans_if(bcx: @Block,
return next_bcx; return next_bcx;
// trans `else [ if { .. } ... | { .. } ]` // trans `else [ if { .. } ... | { .. } ]`
fn trans_if_else(else_bcx_in: @Block, elexpr: @ast::Expr, fn trans_if_else<'a>(
dest: expr::Dest, cleanup: bool) -> @Block { else_bcx_in: &'a Block<'a>,
elexpr: @ast::Expr,
dest: expr::Dest,
cleanup: bool)
-> &'a Block<'a> {
let else_bcx_out = match elexpr.node { let else_bcx_out = match elexpr.node {
ast::ExprIf(_, _, _) => { ast::ExprIf(_, _, _) => {
let elseif_blk = ast_util::block_from_expr(elexpr); let elseif_blk = ast_util::block_from_expr(elexpr);
@ -159,7 +165,10 @@ pub fn trans_if(bcx: @Block,
} }
} }
pub fn join_blocks(parent_bcx: @Block, in_cxs: &[@Block]) -> @Block { pub fn join_blocks<'a>(
parent_bcx: &'a Block<'a>,
in_cxs: &[&'a Block<'a>])
-> &'a Block<'a> {
let out = sub_block(parent_bcx, "join"); let out = sub_block(parent_bcx, "join");
let mut reachable = false; let mut reachable = false;
for bcx in in_cxs.iter() { for bcx in in_cxs.iter() {
@ -174,7 +183,11 @@ pub fn join_blocks(parent_bcx: @Block, in_cxs: &[@Block]) -> @Block {
return out; return out;
} }
pub fn trans_while(bcx: @Block, cond: &ast::Expr, body: &ast::Block) -> @Block { pub fn trans_while<'a>(
bcx: &'a Block<'a>,
cond: &ast::Expr,
body: &ast::Block)
-> &'a Block<'a> {
let _icx = push_ctxt("trans_while"); let _icx = push_ctxt("trans_while");
let next_bcx = sub_block(bcx, "while next"); let next_bcx = sub_block(bcx, "while next");
@ -213,10 +226,11 @@ pub fn trans_while(bcx: @Block, cond: &ast::Expr, body: &ast::Block) -> @Block {
return next_bcx; return next_bcx;
} }
pub fn trans_loop(bcx:@Block, pub fn trans_loop<'a>(
bcx: &'a Block<'a>,
body: &ast::Block, body: &ast::Block,
opt_label: Option<Name>) opt_label: Option<Name>)
-> @Block { -> &'a Block<'a> {
let _icx = push_ctxt("trans_loop"); let _icx = push_ctxt("trans_loop");
let next_bcx = sub_block(bcx, "next"); let next_bcx = sub_block(bcx, "next");
let body_bcx_in = loop_scope_block(bcx, next_bcx, opt_label, "`loop`", let body_bcx_in = loop_scope_block(bcx, next_bcx, opt_label, "`loop`",
@ -227,10 +241,11 @@ pub fn trans_loop(bcx:@Block,
return next_bcx; return next_bcx;
} }
pub fn trans_break_cont(bcx: @Block, pub fn trans_break_cont<'a>(
bcx: &'a Block<'a>,
opt_label: Option<Name>, opt_label: Option<Name>,
to_end: bool) to_end: bool)
-> @Block { -> &'a Block<'a> {
let _icx = push_ctxt("trans_break_cont"); let _icx = push_ctxt("trans_break_cont");
// Locate closest loop block, outputting cleanup as we go. // Locate closest loop block, outputting cleanup as we go.
let mut unwind = bcx; let mut unwind = bcx;
@ -238,7 +253,7 @@ pub fn trans_break_cont(bcx: @Block,
let mut target; let mut target;
loop { loop {
cur_scope = match cur_scope { cur_scope = match cur_scope {
Some(@ScopeInfo { Some(&ScopeInfo {
loop_break: Some(brk), loop_break: Some(brk),
loop_label: l, loop_label: l,
parent, parent,
@ -283,15 +298,18 @@ pub fn trans_break_cont(bcx: @Block,
return bcx; return bcx;
} }
pub fn trans_break(bcx: @Block, label_opt: Option<Name>) -> @Block { pub fn trans_break<'a>(bcx: &'a Block<'a>, label_opt: Option<Name>)
-> &'a Block<'a> {
return trans_break_cont(bcx, label_opt, true); return trans_break_cont(bcx, label_opt, true);
} }
pub fn trans_cont(bcx: @Block, label_opt: Option<Name>) -> @Block { pub fn trans_cont<'a>(bcx: &'a Block<'a>, label_opt: Option<Name>)
-> &'a Block<'a> {
return trans_break_cont(bcx, label_opt, false); return trans_break_cont(bcx, label_opt, false);
} }
pub fn trans_ret(bcx: @Block, e: Option<@ast::Expr>) -> @Block { pub fn trans_ret<'a>(bcx: &'a Block<'a>, e: Option<@ast::Expr>)
-> &'a Block<'a> {
let _icx = push_ctxt("trans_ret"); let _icx = push_ctxt("trans_ret");
let mut bcx = bcx; let mut bcx = bcx;
let dest = match bcx.fcx.llretptr.get() { let dest = match bcx.fcx.llretptr.get() {
@ -309,10 +327,11 @@ pub fn trans_ret(bcx: @Block, e: Option<@ast::Expr>) -> @Block {
return bcx; return bcx;
} }
pub fn trans_fail_expr(bcx: @Block, pub fn trans_fail_expr<'a>(
bcx: &'a Block<'a>,
sp_opt: Option<Span>, sp_opt: Option<Span>,
fail_expr: Option<@ast::Expr>) fail_expr: Option<@ast::Expr>)
-> @Block { -> &'a Block<'a> {
let _icx = push_ctxt("trans_fail_expr"); let _icx = push_ctxt("trans_fail_expr");
let mut bcx = bcx; let mut bcx = bcx;
match fail_expr { match fail_expr {
@ -337,19 +356,21 @@ pub fn trans_fail_expr(bcx: @Block,
} }
} }
pub fn trans_fail(bcx: @Block, pub fn trans_fail<'a>(
bcx: &'a Block<'a>,
sp_opt: Option<Span>, sp_opt: Option<Span>,
fail_str: @str) fail_str: @str)
-> @Block { -> &'a Block<'a> {
let _icx = push_ctxt("trans_fail"); let _icx = push_ctxt("trans_fail");
let V_fail_str = C_cstr(bcx.ccx(), fail_str); let V_fail_str = C_cstr(bcx.ccx(), fail_str);
return trans_fail_value(bcx, sp_opt, V_fail_str); return trans_fail_value(bcx, sp_opt, V_fail_str);
} }
fn trans_fail_value(bcx: @Block, fn trans_fail_value<'a>(
bcx: &'a Block<'a>,
sp_opt: Option<Span>, sp_opt: Option<Span>,
V_fail_str: ValueRef) V_fail_str: ValueRef)
-> @Block { -> &'a Block<'a> {
let _icx = push_ctxt("trans_fail_value"); let _icx = push_ctxt("trans_fail_value");
let ccx = bcx.ccx(); let ccx = bcx.ccx();
let (V_filename, V_line) = match sp_opt { let (V_filename, V_line) = match sp_opt {
@ -372,8 +393,12 @@ fn trans_fail_value(bcx: @Block,
return bcx; return bcx;
} }
pub fn trans_fail_bounds_check(bcx: @Block, sp: Span, pub fn trans_fail_bounds_check<'a>(
index: ValueRef, len: ValueRef) -> @Block { bcx: &'a Block<'a>,
sp: Span,
index: ValueRef,
len: ValueRef)
-> &'a Block<'a> {
let _icx = push_ctxt("trans_fail_bounds_check"); let _icx = push_ctxt("trans_fail_bounds_check");
let (filename, line) = filename_and_line_num_from_span(bcx, sp); let (filename, line) = filename_and_line_num_from_span(bcx, sp);
let args = ~[filename, line, index, len]; let args = ~[filename, line, index, len];

View File

@ -125,8 +125,8 @@ pub struct Datum {
mode: DatumMode, mode: DatumMode,
} }
pub struct DatumBlock { pub struct DatumBlock<'a> {
bcx: @Block, bcx: &'a Block<'a>,
datum: Datum, datum: Datum,
} }
@ -163,14 +163,16 @@ pub fn immediate_rvalue(val: ValueRef, ty: ty::t) -> Datum {
return Datum {val: val, ty: ty, mode: ByValue}; return Datum {val: val, ty: ty, mode: ByValue};
} }
pub fn immediate_rvalue_bcx(bcx: @Block, pub fn immediate_rvalue_bcx<'a>(bcx: &'a Block<'a>, val: ValueRef, ty: ty::t)
val: ValueRef, -> DatumBlock<'a> {
ty: ty::t) DatumBlock {
-> DatumBlock { bcx: bcx,
return DatumBlock {bcx: bcx, datum: immediate_rvalue(val, ty)}; datum: immediate_rvalue(val, ty),
}
} }
pub fn scratch_datum(bcx: @Block, ty: ty::t, name: &str, zero: bool) -> Datum { pub fn scratch_datum(bcx: &Block, ty: ty::t, name: &str, zero: bool)
-> Datum {
/*! /*!
* Allocates temporary space on the stack using alloca() and * Allocates temporary space on the stack using alloca() and
* returns a by-ref Datum pointing to it. If `zero` is true, the * returns a by-ref Datum pointing to it. If `zero` is true, the
@ -203,11 +205,12 @@ pub fn appropriate_mode(ccx: &CrateContext, ty: ty::t) -> DatumMode {
} }
impl Datum { impl Datum {
pub fn store_to(&self, pub fn store_to<'a>(
bcx: @Block, &self,
bcx: &'a Block<'a>,
action: CopyAction, action: CopyAction,
dst: ValueRef) dst: ValueRef)
-> @Block { -> &'a Block<'a> {
/*! /*!
* *
* Stores this value into its final home. This moves if * Stores this value into its final home. This moves if
@ -221,10 +224,8 @@ impl Datum {
} }
} }
pub fn store_to_dest(&self, pub fn store_to_dest<'a>(&self, bcx: &'a Block<'a>, dest: expr::Dest)
bcx: @Block, -> &'a Block<'a> {
dest: expr::Dest)
-> @Block {
match dest { match dest {
expr::Ignore => { expr::Ignore => {
return bcx; return bcx;
@ -235,31 +236,44 @@ impl Datum {
} }
} }
pub fn store_to_datum(&self, pub fn store_to_datum<'a>(
bcx: @Block, &self,
bcx: &'a Block<'a>,
action: CopyAction, action: CopyAction,
datum: Datum) datum: Datum)
-> @Block { -> &'a Block<'a> {
debug!("store_to_datum(self={}, action={:?}, datum={})", debug!("store_to_datum(self={}, action={:?}, datum={})",
self.to_str(bcx.ccx()), action, datum.to_str(bcx.ccx())); self.to_str(bcx.ccx()), action, datum.to_str(bcx.ccx()));
assert!(datum.mode.is_by_ref()); assert!(datum.mode.is_by_ref());
self.store_to(bcx, action, datum.val) self.store_to(bcx, action, datum.val)
} }
pub fn move_to_datum(&self, bcx: @Block, action: CopyAction, datum: Datum) pub fn move_to_datum<'a>(
-> @Block { &self,
bcx: &'a Block<'a>,
action: CopyAction,
datum: Datum)
-> &'a Block<'a> {
assert!(datum.mode.is_by_ref()); assert!(datum.mode.is_by_ref());
self.move_to(bcx, action, datum.val) self.move_to(bcx, action, datum.val)
} }
pub fn copy_to_datum(&self, bcx: @Block, action: CopyAction, datum: Datum) pub fn copy_to_datum<'a>(
-> @Block { &self,
bcx: &'a Block<'a>,
action: CopyAction,
datum: Datum)
-> &'a Block<'a> {
assert!(datum.mode.is_by_ref()); assert!(datum.mode.is_by_ref());
self.copy_to(bcx, action, datum.val) self.copy_to(bcx, action, datum.val)
} }
pub fn copy_to(&self, bcx: @Block, action: CopyAction, dst: ValueRef) pub fn copy_to<'a>(
-> @Block { &self,
bcx: &'a Block<'a>,
action: CopyAction,
dst: ValueRef)
-> &'a Block<'a> {
/*! /*!
* *
* Copies the value into `dst`, which should be a pointer to a * Copies the value into `dst`, which should be a pointer to a
@ -301,11 +315,12 @@ impl Datum {
} }
} }
pub fn copy_to_no_check(&self, pub fn copy_to_no_check<'a>(
bcx: @Block, &self,
bcx: &'a Block<'a>,
action: CopyAction, action: CopyAction,
dst: ValueRef) dst: ValueRef)
-> @Block { -> &'a Block<'a> {
/*! /*!
* *
* A helper for `copy_to()` which does not check to see if we * A helper for `copy_to()` which does not check to see if we
@ -333,8 +348,12 @@ impl Datum {
// This works like copy_val, except that it deinitializes the source. // This works like copy_val, except that it deinitializes the source.
// Since it needs to zero out the source, src also needs to be an lval. // Since it needs to zero out the source, src also needs to be an lval.
// //
pub fn move_to(&self, bcx: @Block, action: CopyAction, dst: ValueRef) pub fn move_to<'a>(
-> @Block { &self,
bcx: &'a Block<'a>,
action: CopyAction,
dst: ValueRef)
-> &'a Block<'a> {
let _icx = push_ctxt("move_to"); let _icx = push_ctxt("move_to");
let mut bcx = bcx; let mut bcx = bcx;
@ -363,7 +382,7 @@ impl Datum {
return bcx; return bcx;
} }
pub fn add_clean(&self, bcx: @Block) { pub fn add_clean(&self, bcx: &Block) {
/*! /*!
* Schedules this datum for cleanup in `bcx`. The datum * Schedules this datum for cleanup in `bcx`. The datum
* must be an rvalue. * must be an rvalue.
@ -383,7 +402,7 @@ impl Datum {
} }
} }
pub fn cancel_clean(&self, bcx: @Block) { pub fn cancel_clean(&self, bcx: &Block) {
if ty::type_needs_drop(bcx.tcx(), self.ty) { if ty::type_needs_drop(bcx.tcx(), self.ty) {
match self.mode { match self.mode {
ByValue | ByValue |
@ -408,7 +427,7 @@ impl Datum {
self.mode) self.mode)
} }
pub fn to_value_datum(&self, bcx: @Block) -> Datum { pub fn to_value_datum(&self, bcx: &Block) -> Datum {
/*! /*!
* *
* Yields a by-value form of this datum. This may involve * Yields a by-value form of this datum. This may involve
@ -425,7 +444,7 @@ impl Datum {
} }
} }
pub fn to_value_llval(&self, bcx: @Block) -> ValueRef { pub fn to_value_llval(&self, bcx: &Block) -> ValueRef {
/*! /*!
* *
* Yields the value itself. */ * Yields the value itself. */
@ -446,7 +465,7 @@ impl Datum {
} }
} }
pub fn to_ref_datum(&self, bcx: @Block) -> Datum { pub fn to_ref_datum(&self, bcx: &Block) -> Datum {
/*! /*!
* Yields a by-ref form of this datum. This may involve * Yields a by-ref form of this datum. This may involve
* creation of a temporary stack slot. The value returned by * creation of a temporary stack slot. The value returned by
@ -463,7 +482,7 @@ impl Datum {
} }
} }
pub fn to_ref_llval(&self, bcx: @Block) -> ValueRef { pub fn to_ref_llval(&self, bcx: &Block) -> ValueRef {
match self.mode { match self.mode {
ByRef(_) => self.val, ByRef(_) => self.val,
ByValue => { ByValue => {
@ -496,7 +515,7 @@ impl Datum {
appropriate_mode(ccx, self.ty) appropriate_mode(ccx, self.ty)
} }
pub fn to_appropriate_llval(&self, bcx: @Block) -> ValueRef { pub fn to_appropriate_llval(&self, bcx: &Block) -> ValueRef {
/*! /*!
* *
* Yields an llvalue with the `appropriate_mode()`. */ * Yields an llvalue with the `appropriate_mode()`. */
@ -507,7 +526,7 @@ impl Datum {
} }
} }
pub fn to_appropriate_datum(&self, bcx: @Block) -> Datum { pub fn to_appropriate_datum(&self, bcx: &Block) -> Datum {
/*! /*!
* *
* Yields a datum with the `appropriate_mode()`. */ * Yields a datum with the `appropriate_mode()`. */
@ -519,7 +538,7 @@ impl Datum {
} }
pub fn get_element(&self, pub fn get_element(&self,
bcx: @Block, bcx: &Block,
ty: ty::t, ty: ty::t,
source: DatumCleanup, source: DatumCleanup,
gep: |ValueRef| -> ValueRef) gep: |ValueRef| -> ValueRef)
@ -532,7 +551,7 @@ impl Datum {
} }
} }
pub fn drop_val(&self, bcx: @Block) -> @Block { pub fn drop_val<'a>(&self, bcx: &'a Block<'a>) -> &'a Block<'a> {
if !ty::type_needs_drop(bcx.tcx(), self.ty) { if !ty::type_needs_drop(bcx.tcx(), self.ty) {
return bcx; return bcx;
} }
@ -543,7 +562,7 @@ impl Datum {
}; };
} }
pub fn box_body(&self, bcx: @Block) -> Datum { pub fn box_body(&self, bcx: &Block) -> Datum {
/*! /*!
* *
* This datum must represent an @T or ~T box. Returns a new * This datum must represent an @T or ~T box. Returns a new
@ -576,7 +595,7 @@ impl Datum {
} }
} }
pub fn to_rptr(&self, bcx: @Block) -> Datum { pub fn to_rptr(&self, bcx: &Block) -> Datum {
//! Returns a new datum of region-pointer type containing the //! Returns a new datum of region-pointer type containing the
//! the same ptr as this datum (after converting to by-ref //! the same ptr as this datum (after converting to by-ref
//! using `to_ref_llval()`). //! using `to_ref_llval()`).
@ -596,13 +615,14 @@ impl Datum {
/// expr_id: ID of deref expr. /// expr_id: ID of deref expr.
/// derefs: Number of times deref'd already. /// derefs: Number of times deref'd already.
/// is_auto: If true, only deref if auto-derefable. /// is_auto: If true, only deref if auto-derefable.
pub fn try_deref(&self, pub fn try_deref<'a>(
bcx: @Block, &self,
bcx: &'a Block<'a>,
span: Span, span: Span,
expr_id: ast::NodeId, expr_id: ast::NodeId,
derefs: uint, derefs: uint,
is_auto: bool) is_auto: bool)
-> (Option<Datum>, @Block) { -> (Option<Datum>, &'a Block<'a>) {
debug!("try_deref(expr_id={:?}, derefs={:?}, is_auto={}, self={:?})", debug!("try_deref(expr_id={:?}, derefs={:?}, is_auto={}, self={:?})",
expr_id, derefs, is_auto, self.to_str(bcx.ccx())); expr_id, derefs, is_auto, self.to_str(bcx.ccx()));
@ -629,7 +649,7 @@ impl Datum {
} }
} }
fn deref_ptr(bcx: @Block, lv: &Datum, ty: ty::t) -> Datum { fn deref_ptr(bcx: &Block, lv: &Datum, ty: ty::t) -> Datum {
Datum { Datum {
val: lv.to_value_llval(bcx), val: lv.to_value_llval(bcx),
ty: ty, ty: ty,
@ -639,8 +659,12 @@ impl Datum {
} }
/// expr: The deref expression. /// expr: The deref expression.
pub fn deref(&self, bcx: @Block, expr: &ast::Expr, derefs: uint) pub fn deref<'a>(
-> DatumBlock { &self,
bcx: &'a Block<'a>,
expr: &ast::Expr,
derefs: uint)
-> DatumBlock<'a> {
match self.try_deref(bcx, expr.span, expr.id, derefs, false) { match self.try_deref(bcx, expr.span, expr.id, derefs, false) {
(Some(lvres), bcx) => DatumBlock { bcx: bcx, datum: lvres }, (Some(lvres), bcx) => DatumBlock { bcx: bcx, datum: lvres },
(None, _) => { (None, _) => {
@ -650,12 +674,13 @@ impl Datum {
} }
} }
pub fn autoderef(&self, pub fn autoderef<'a>(
bcx: @Block, &self,
bcx: &'a Block<'a>,
span: Span, span: Span,
expr_id: ast::NodeId, expr_id: ast::NodeId,
max: uint) max: uint)
-> DatumBlock { -> DatumBlock<'a> {
let _icx = push_ctxt("autoderef"); let _icx = push_ctxt("autoderef");
debug!("autoderef(expr_id={}, max={:?}, self={:?})", debug!("autoderef(expr_id={}, max={:?}, self={:?})",
@ -683,12 +708,13 @@ impl Datum {
DatumBlock { bcx: bcx, datum: datum } DatumBlock { bcx: bcx, datum: datum }
} }
pub fn get_vec_base_and_byte_len(&self, pub fn get_vec_base_and_byte_len<'a>(
mut bcx: @Block, &self,
mut bcx: &'a Block<'a>,
span: Span, span: Span,
expr_id: ast::NodeId, expr_id: ast::NodeId,
derefs: uint) derefs: uint)
-> (@Block, ValueRef, ValueRef) { -> (&'a Block<'a>, ValueRef, ValueRef) {
//! Converts a vector into the slice pair. Performs rooting //! Converts a vector into the slice pair. Performs rooting
//! and write guards checks. //! and write guards checks.
@ -698,7 +724,7 @@ impl Datum {
(bcx, base, len) (bcx, base, len)
} }
pub fn get_vec_base_and_byte_len_no_root(&self, bcx: @Block) pub fn get_vec_base_and_byte_len_no_root(&self, bcx: &Block)
-> (ValueRef, ValueRef) { -> (ValueRef, ValueRef) {
//! Converts a vector into the slice pair. Des not root //! Converts a vector into the slice pair. Des not root
//! nor perform write guard checks. //! nor perform write guard checks.
@ -707,12 +733,13 @@ impl Datum {
tvec::get_base_and_byte_len(bcx, llval, self.ty) tvec::get_base_and_byte_len(bcx, llval, self.ty)
} }
pub fn get_vec_base_and_len(&self, pub fn get_vec_base_and_len<'a>(
mut bcx: @Block, &self,
mut bcx: &'a Block<'a>,
span: Span, span: Span,
expr_id: ast::NodeId, expr_id: ast::NodeId,
derefs: uint) derefs: uint)
-> (@Block, ValueRef, ValueRef) { -> (&'a Block<'a>, ValueRef, ValueRef) {
//! Converts a vector into the slice pair. Performs rooting //! Converts a vector into the slice pair. Performs rooting
//! and write guards checks. //! and write guards checks.
@ -722,7 +749,7 @@ impl Datum {
(bcx, base, len) (bcx, base, len)
} }
pub fn get_vec_base_and_len_no_root(&self, bcx: @Block) pub fn get_vec_base_and_len_no_root<'a>(&self, bcx: &'a Block<'a>)
-> (ValueRef, ValueRef) { -> (ValueRef, ValueRef) {
//! Converts a vector into the slice pair. Des not root //! Converts a vector into the slice pair. Des not root
//! nor perform write guard checks. //! nor perform write guard checks.
@ -731,47 +758,48 @@ impl Datum {
tvec::get_base_and_len(bcx, llval, self.ty) tvec::get_base_and_len(bcx, llval, self.ty)
} }
pub fn root_and_write_guard(&self, pub fn root_and_write_guard<'a>(
bcx: @Block, &self,
bcx: &'a Block<'a>,
span: Span, span: Span,
expr_id: ast::NodeId, expr_id: ast::NodeId,
derefs: uint) derefs: uint)
-> @Block { -> &'a Block<'a> {
write_guard::root_and_write_guard(self, bcx, span, expr_id, derefs) write_guard::root_and_write_guard(self, bcx, span, expr_id, derefs)
} }
pub fn to_result(&self, bcx: @Block) -> common::Result { pub fn to_result<'a>(&self, bcx: &'a Block<'a>) -> common::Result<'a> {
rslt(bcx, self.to_appropriate_llval(bcx)) rslt(bcx, self.to_appropriate_llval(bcx))
} }
} }
impl DatumBlock { impl<'a> DatumBlock<'a> {
pub fn unpack(&self, bcx: &mut @Block) -> Datum { pub fn unpack(&self, bcx: &mut &'a Block<'a>) -> Datum {
*bcx = self.bcx; *bcx = self.bcx;
return self.datum; return self.datum;
} }
pub fn assert_by_ref(&self) -> DatumBlock { pub fn assert_by_ref(&self) -> DatumBlock<'a> {
assert!(self.datum.mode.is_by_ref()); assert!(self.datum.mode.is_by_ref());
*self *self
} }
pub fn drop_val(&self) -> @Block { pub fn drop_val(&self) -> &'a Block<'a> {
self.datum.drop_val(self.bcx) self.datum.drop_val(self.bcx)
} }
pub fn store_to(&self, pub fn store_to(&self, action: CopyAction, dst: ValueRef)
action: CopyAction, -> &'a Block<'a> {
dst: ValueRef)
-> @Block {
self.datum.store_to(self.bcx, action, dst) self.datum.store_to(self.bcx, action, dst)
} }
pub fn copy_to(&self, action: CopyAction, dst: ValueRef) -> @Block { pub fn copy_to(&self, action: CopyAction, dst: ValueRef)
-> &'a Block<'a> {
self.datum.copy_to(self.bcx, action, dst) self.datum.copy_to(self.bcx, action, dst)
} }
pub fn move_to(&self, action: CopyAction, dst: ValueRef) -> @Block { pub fn move_to(&self, action: CopyAction, dst: ValueRef)
-> &'a Block<'a> {
self.datum.move_to(self.bcx, action, dst) self.datum.move_to(self.bcx, action, dst)
} }
@ -779,7 +807,7 @@ impl DatumBlock {
self.datum.to_value_llval(self.bcx) self.datum.to_value_llval(self.bcx)
} }
pub fn to_result(&self) -> common::Result { pub fn to_result(&self) -> common::Result<'a> {
rslt(self.bcx, self.datum.to_appropriate_llval(self.bcx)) rslt(self.bcx, self.datum.to_appropriate_llval(self.bcx))
} }

View File

@ -270,8 +270,7 @@ pub fn finalize(cx: @CrateContext) {
/// Creates debug information for the given local variable. /// Creates debug information for the given local variable.
/// ///
/// Adds the created metadata nodes directly to the crate's IR. /// Adds the created metadata nodes directly to the crate's IR.
pub fn create_local_var_metadata(bcx: @Block, pub fn create_local_var_metadata(bcx: &Block, local: &ast::Local) {
local: &ast::Local) {
if fn_should_be_ignored(bcx.fcx) { if fn_should_be_ignored(bcx.fcx) {
return; return;
} }
@ -310,7 +309,7 @@ pub fn create_local_var_metadata(bcx: @Block,
/// Creates debug information for a variable captured in a closure. /// Creates debug information for a variable captured in a closure.
/// ///
/// Adds the created metadata nodes directly to the crate's IR. /// Adds the created metadata nodes directly to the crate's IR.
pub fn create_captured_var_metadata(bcx: @Block, pub fn create_captured_var_metadata(bcx: &Block,
node_id: ast::NodeId, node_id: ast::NodeId,
env_data_type: ty::t, env_data_type: ty::t,
env_pointer: ValueRef, env_pointer: ValueRef,
@ -380,7 +379,7 @@ pub fn create_captured_var_metadata(bcx: @Block,
/// Creates debug information for a local variable introduced in the head of a match-statement arm. /// Creates debug information for a local variable introduced in the head of a match-statement arm.
/// ///
/// Adds the created metadata nodes directly to the crate's IR. /// Adds the created metadata nodes directly to the crate's IR.
pub fn create_match_binding_metadata(bcx: @Block, pub fn create_match_binding_metadata(bcx: &Block,
variable_ident: ast::Ident, variable_ident: ast::Ident,
node_id: ast::NodeId, node_id: ast::NodeId,
variable_type: ty::t, variable_type: ty::t,
@ -417,7 +416,7 @@ pub fn create_match_binding_metadata(bcx: @Block,
/// Creates debug information for the self argument of a method. /// Creates debug information for the self argument of a method.
/// ///
/// Adds the created metadata nodes directly to the crate's IR. /// Adds the created metadata nodes directly to the crate's IR.
pub fn create_self_argument_metadata(bcx: @Block, pub fn create_self_argument_metadata(bcx: &Block,
type_of_self: ty::t, type_of_self: ty::t,
llptr: ValueRef) { llptr: ValueRef) {
if fn_should_be_ignored(bcx.fcx) { if fn_should_be_ignored(bcx.fcx) {
@ -495,8 +494,7 @@ pub fn create_self_argument_metadata(bcx: @Block,
/// Creates debug information for the given function argument. /// Creates debug information for the given function argument.
/// ///
/// Adds the created metadata nodes directly to the crate's IR. /// Adds the created metadata nodes directly to the crate's IR.
pub fn create_argument_metadata(bcx: @Block, pub fn create_argument_metadata(bcx: &Block, arg: &ast::arg) {
arg: &ast::arg) {
if fn_should_be_ignored(bcx.fcx) { if fn_should_be_ignored(bcx.fcx) {
return; return;
} }
@ -973,7 +971,7 @@ fn compile_unit_metadata(cx: @CrateContext) {
}); });
} }
fn declare_local(bcx: @Block, fn declare_local(bcx: &Block,
variable_ident: ast::Ident, variable_ident: ast::Ident,
variable_type: ty::t, variable_type: ty::t,
scope_metadata: DIScope, scope_metadata: DIScope,

View File

@ -175,7 +175,8 @@ impl Dest {
} }
} }
pub fn trans_to_datum(bcx: @Block, expr: &ast::Expr) -> DatumBlock { pub fn trans_to_datum<'a>(bcx: &'a Block<'a>, expr: &ast::Expr)
-> DatumBlock<'a> {
debug!("trans_to_datum(expr={})", bcx.expr_to_str(expr)); debug!("trans_to_datum(expr={})", bcx.expr_to_str(expr));
let mut bcx = bcx; let mut bcx = bcx;
@ -249,13 +250,15 @@ pub fn trans_to_datum(bcx: @Block, expr: &ast::Expr) -> DatumBlock {
debug!("after adjustments, datum={}", datum.to_str(bcx.ccx())); debug!("after adjustments, datum={}", datum.to_str(bcx.ccx()));
return DatumBlock {bcx: bcx, datum: datum}; return DatumBlock {bcx: bcx, datum: datum};
fn auto_ref(bcx: @Block, datum: Datum) -> DatumBlock { fn auto_ref<'a>(bcx: &'a Block<'a>, datum: Datum) -> DatumBlock<'a> {
DatumBlock {bcx: bcx, datum: datum.to_rptr(bcx)} DatumBlock {bcx: bcx, datum: datum.to_rptr(bcx)}
} }
fn auto_borrow_fn(bcx: @Block, fn auto_borrow_fn<'a>(
bcx: &'a Block<'a>,
adjusted_ty: ty::t, adjusted_ty: ty::t,
datum: Datum) -> DatumBlock { datum: Datum)
-> DatumBlock<'a> {
// Currently, all closure types are represented precisely the // Currently, all closure types are represented precisely the
// same, so no runtime adjustment is required, but we still // same, so no runtime adjustment is required, but we still
// must patchup the type. // must patchup the type.
@ -264,10 +267,12 @@ pub fn trans_to_datum(bcx: @Block, expr: &ast::Expr) -> DatumBlock {
mode: datum.mode}} mode: datum.mode}}
} }
fn auto_slice(bcx: @Block, fn auto_slice<'a>(
bcx: &'a Block<'a>,
autoderefs: uint, autoderefs: uint,
expr: &ast::Expr, expr: &ast::Expr,
datum: Datum) -> DatumBlock { datum: Datum)
-> DatumBlock<'a> {
// This is not the most efficient thing possible; since slices // This is not the most efficient thing possible; since slices
// are two words it'd be better if this were compiled in // are two words it'd be better if this were compiled in
// 'dest' mode, but I can't find a nice way to structure the // 'dest' mode, but I can't find a nice way to structure the
@ -293,7 +298,8 @@ pub fn trans_to_datum(bcx: @Block, expr: &ast::Expr) -> DatumBlock {
DatumBlock {bcx: bcx, datum: scratch} DatumBlock {bcx: bcx, datum: scratch}
} }
fn add_env(bcx: @Block, expr: &ast::Expr, datum: Datum) -> DatumBlock { fn add_env<'a>(bcx: &'a Block<'a>, expr: &ast::Expr, datum: Datum)
-> DatumBlock<'a> {
// This is not the most efficient thing possible; since closures // This is not the most efficient thing possible; since closures
// are two words it'd be better if this were compiled in // are two words it'd be better if this were compiled in
// 'dest' mode, but I can't find a nice way to structure the // 'dest' mode, but I can't find a nice way to structure the
@ -312,18 +318,22 @@ pub fn trans_to_datum(bcx: @Block, expr: &ast::Expr) -> DatumBlock {
DatumBlock {bcx: bcx, datum: scratch} DatumBlock {bcx: bcx, datum: scratch}
} }
fn auto_slice_and_ref(bcx: @Block, fn auto_slice_and_ref<'a>(
bcx: &'a Block<'a>,
autoderefs: uint, autoderefs: uint,
expr: &ast::Expr, expr: &ast::Expr,
datum: Datum) -> DatumBlock { datum: Datum)
-> DatumBlock<'a> {
let DatumBlock { bcx, datum } = auto_slice(bcx, autoderefs, expr, datum); let DatumBlock { bcx, datum } = auto_slice(bcx, autoderefs, expr, datum);
auto_ref(bcx, datum) auto_ref(bcx, datum)
} }
fn auto_borrow_obj(mut bcx: @Block, fn auto_borrow_obj<'a>(
mut bcx: &'a Block<'a>,
autoderefs: uint, autoderefs: uint,
expr: &ast::Expr, expr: &ast::Expr,
source_datum: Datum) -> DatumBlock { source_datum: Datum)
-> DatumBlock<'a> {
let tcx = bcx.tcx(); let tcx = bcx.tcx();
let target_obj_ty = expr_ty_adjusted(bcx, expr); let target_obj_ty = expr_ty_adjusted(bcx, expr);
debug!("auto_borrow_obj(target={})", debug!("auto_borrow_obj(target={})",
@ -428,7 +438,8 @@ pub fn trans_to_datum(bcx: @Block, expr: &ast::Expr) -> DatumBlock {
} }
} }
pub fn trans_into(bcx: @Block, expr: &ast::Expr, dest: Dest) -> @Block { pub fn trans_into<'a>(bcx: &'a Block<'a>, expr: &ast::Expr, dest: Dest)
-> &'a Block<'a> {
let adjustment_found = { let adjustment_found = {
let adjustments = bcx.tcx().adjustments.borrow(); let adjustments = bcx.tcx().adjustments.borrow();
adjustments.get().contains_key(&expr.id) adjustments.get().contains_key(&expr.id)
@ -446,7 +457,11 @@ pub fn trans_into(bcx: @Block, expr: &ast::Expr, dest: Dest) -> @Block {
trans_into_unadjusted(bcx, expr, dest) trans_into_unadjusted(bcx, expr, dest)
} }
pub fn trans_into_unadjusted(bcx: @Block, expr: &ast::Expr, dest: Dest) -> @Block { pub fn trans_into_unadjusted<'a>(
bcx: &'a Block<'a>,
expr: &ast::Expr,
dest: Dest)
-> &'a Block<'a> {
let ty = expr_ty(bcx, expr); let ty = expr_ty(bcx, expr);
debug!("trans_into_unadjusted(expr={}, dest={})", debug!("trans_into_unadjusted(expr={}, dest={})",
@ -494,7 +509,7 @@ pub fn trans_into_unadjusted(bcx: @Block, expr: &ast::Expr, dest: Dest) -> @Bloc
}; };
} }
fn trans_lvalue(bcx: @Block, expr: &ast::Expr) -> DatumBlock { fn trans_lvalue<'a>(bcx: &'a Block<'a>, expr: &ast::Expr) -> DatumBlock<'a> {
/*! /*!
* *
* Translates an lvalue expression, always yielding a by-ref * Translates an lvalue expression, always yielding a by-ref
@ -517,7 +532,8 @@ fn trans_lvalue(bcx: @Block, expr: &ast::Expr) -> DatumBlock {
} }
} }
fn trans_to_datum_unadjusted(bcx: @Block, expr: &ast::Expr) -> DatumBlock { fn trans_to_datum_unadjusted<'a>(bcx: &'a Block<'a>, expr: &ast::Expr)
-> DatumBlock<'a> {
/*! /*!
* Translates an expression into a datum. If this expression * Translates an expression into a datum. If this expression
* is an rvalue, this will result in a temporary value being * is an rvalue, this will result in a temporary value being
@ -577,13 +593,17 @@ fn trans_to_datum_unadjusted(bcx: @Block, expr: &ast::Expr) -> DatumBlock {
} }
} }
fn nil(bcx: @Block, ty: ty::t) -> DatumBlock { fn nil<'a>(bcx: &'a Block<'a>, ty: ty::t) -> DatumBlock<'a> {
let datum = immediate_rvalue(C_nil(), ty); let datum = immediate_rvalue(C_nil(), ty);
DatumBlock {bcx: bcx, datum: datum} DatumBlock {
bcx: bcx,
datum: datum,
}
} }
} }
fn trans_rvalue_datum_unadjusted(bcx: @Block, expr: &ast::Expr) -> DatumBlock { fn trans_rvalue_datum_unadjusted<'a>(bcx: &'a Block<'a>, expr: &ast::Expr)
-> DatumBlock<'a> {
let _icx = push_ctxt("trans_rvalue_datum_unadjusted"); let _icx = push_ctxt("trans_rvalue_datum_unadjusted");
match expr.node { match expr.node {
@ -636,7 +656,8 @@ fn trans_rvalue_datum_unadjusted(bcx: @Block, expr: &ast::Expr) -> DatumBlock {
} }
} }
fn trans_rvalue_stmt_unadjusted(bcx: @Block, expr: &ast::Expr) -> @Block { fn trans_rvalue_stmt_unadjusted<'a>(bcx: &'a Block<'a>, expr: &ast::Expr)
-> &'a Block<'a> {
let mut bcx = bcx; let mut bcx = bcx;
let _icx = push_ctxt("trans_rvalue_stmt"); let _icx = push_ctxt("trans_rvalue_stmt");
@ -688,8 +709,11 @@ fn trans_rvalue_stmt_unadjusted(bcx: @Block, expr: &ast::Expr) -> @Block {
}; };
} }
fn trans_rvalue_dps_unadjusted(bcx: @Block, expr: &ast::Expr, fn trans_rvalue_dps_unadjusted<'a>(
dest: Dest) -> @Block { bcx: &'a Block<'a>,
expr: &ast::Expr,
dest: Dest)
-> &'a Block<'a> {
let _icx = push_ctxt("trans_rvalue_dps_unadjusted"); let _icx = push_ctxt("trans_rvalue_dps_unadjusted");
let tcx = bcx.tcx(); let tcx = bcx.tcx();
@ -813,8 +837,12 @@ fn trans_rvalue_dps_unadjusted(bcx: @Block, expr: &ast::Expr,
} }
} }
fn trans_def_dps_unadjusted(bcx: @Block, ref_expr: &ast::Expr, fn trans_def_dps_unadjusted<'a>(
def: ast::Def, dest: Dest) -> @Block { bcx: &'a Block<'a>,
ref_expr: &ast::Expr,
def: ast::Def,
dest: Dest)
-> &'a Block<'a> {
let _icx = push_ctxt("trans_def_dps_unadjusted"); let _icx = push_ctxt("trans_def_dps_unadjusted");
let ccx = bcx.ccx(); let ccx = bcx.ccx();
@ -863,10 +891,11 @@ fn trans_def_dps_unadjusted(bcx: @Block, ref_expr: &ast::Expr,
} }
} }
fn trans_def_datum_unadjusted(bcx: @Block, fn trans_def_datum_unadjusted<'a>(
bcx: &'a Block<'a>,
ref_expr: &ast::Expr, ref_expr: &ast::Expr,
def: ast::Def) -> DatumBlock def: ast::Def)
{ -> DatumBlock<'a> {
let _icx = push_ctxt("trans_def_datum_unadjusted"); let _icx = push_ctxt("trans_def_datum_unadjusted");
let fn_data = match def { let fn_data = match def {
@ -898,7 +927,8 @@ fn trans_def_datum_unadjusted(bcx: @Block,
} }
} }
fn trans_lvalue_unadjusted(bcx: @Block, expr: &ast::Expr) -> DatumBlock { fn trans_lvalue_unadjusted<'a>(bcx: &'a Block<'a>, expr: &ast::Expr)
-> DatumBlock<'a> {
/*! /*!
* *
* Translates an lvalue expression, always yielding a by-ref * Translates an lvalue expression, always yielding a by-ref
@ -935,9 +965,11 @@ fn trans_lvalue_unadjusted(bcx: @Block, expr: &ast::Expr) -> DatumBlock {
} }
}; };
fn trans_rec_field(bcx: @Block, fn trans_rec_field<'a>(
bcx: &'a Block<'a>,
base: &ast::Expr, base: &ast::Expr,
field: ast::Ident) -> DatumBlock { field: ast::Ident)
-> DatumBlock<'a> {
//! Translates `base.field`. //! Translates `base.field`.
let mut bcx = bcx; let mut bcx = bcx;
@ -959,10 +991,12 @@ fn trans_lvalue_unadjusted(bcx: @Block, expr: &ast::Expr) -> DatumBlock {
}) })
} }
fn trans_index(bcx: @Block, fn trans_index<'a>(
bcx: &'a Block<'a>,
index_expr: &ast::Expr, index_expr: &ast::Expr,
base: &ast::Expr, base: &ast::Expr,
idx: &ast::Expr) -> DatumBlock { idx: &ast::Expr)
-> DatumBlock<'a> {
//! Translates `base[idx]`. //! Translates `base[idx]`.
let _icx = push_ctxt("trans_index"); let _icx = push_ctxt("trans_index");
@ -1013,11 +1047,11 @@ fn trans_lvalue_unadjusted(bcx: @Block, expr: &ast::Expr) -> DatumBlock {
}; };
} }
fn trans_def_lvalue(bcx: @Block, fn trans_def_lvalue<'a>(
bcx: &'a Block<'a>,
ref_expr: &ast::Expr, ref_expr: &ast::Expr,
def: ast::Def) def: ast::Def)
-> DatumBlock -> DatumBlock<'a> {
{
//! Translates a reference to a path. //! Translates a reference to a path.
let _icx = push_ctxt("trans_def_lvalue"); let _icx = push_ctxt("trans_def_lvalue");
@ -1034,7 +1068,7 @@ fn trans_lvalue_unadjusted(bcx: @Block, expr: &ast::Expr) -> DatumBlock {
} }
} }
fn get_val(bcx: @Block, did: ast::DefId, const_ty: ty::t) fn get_val(bcx: &Block, did: ast::DefId, const_ty: ty::t)
-> ValueRef { -> ValueRef {
// For external constants, we don't inline. // For external constants, we don't inline.
if did.crate == ast::LOCAL_CRATE { if did.crate == ast::LOCAL_CRATE {
@ -1094,7 +1128,7 @@ fn trans_lvalue_unadjusted(bcx: @Block, expr: &ast::Expr) -> DatumBlock {
} }
} }
pub fn trans_local_var(bcx: @Block, def: ast::Def) -> Datum { pub fn trans_local_var(bcx: &Block, def: ast::Def) -> Datum {
let _icx = push_ctxt("trans_local_var"); let _icx = push_ctxt("trans_local_var");
return match def { return match def {
@ -1149,9 +1183,10 @@ pub fn trans_local_var(bcx: @Block, def: ast::Def) -> Datum {
} }
}; };
fn take_local(bcx: @Block, fn take_local(bcx: &Block,
table: &HashMap<ast::NodeId, ValueRef>, table: &HashMap<ast::NodeId, ValueRef>,
nid: ast::NodeId) -> Datum { nid: ast::NodeId)
-> Datum {
let v = match table.find(&nid) { let v = match table.find(&nid) {
Some(&v) => v, Some(&v) => v,
None => { None => {
@ -1222,13 +1257,14 @@ pub fn with_field_tys<R>(
} }
} }
fn trans_rec_or_struct(bcx: @Block, fn trans_rec_or_struct<'a>(
bcx: &'a Block<'a>,
fields: &[ast::Field], fields: &[ast::Field],
base: Option<@ast::Expr>, base: Option<@ast::Expr>,
expr_span: codemap::Span, expr_span: codemap::Span,
id: ast::NodeId, id: ast::NodeId,
dest: Dest) -> @Block dest: Dest)
{ -> &'a Block<'a> {
let _icx = push_ctxt("trans_rec"); let _icx = push_ctxt("trans_rec");
let bcx = bcx; let bcx = bcx;
@ -1301,10 +1337,14 @@ struct StructBaseInfo {
* - `optbase` contains information on the base struct (if any) from * - `optbase` contains information on the base struct (if any) from
* which remaining fields are copied; see comments on `StructBaseInfo`. * which remaining fields are copied; see comments on `StructBaseInfo`.
*/ */
fn trans_adt(bcx: @Block, repr: &adt::Repr, discr: ty::Disr, fn trans_adt<'a>(
bcx: &'a Block<'a>,
repr: &adt::Repr,
discr: ty::Disr,
fields: &[(uint, @ast::Expr)], fields: &[(uint, @ast::Expr)],
optbase: Option<StructBaseInfo>, optbase: Option<StructBaseInfo>,
dest: Dest) -> @Block { dest: Dest)
-> &'a Block<'a> {
let _icx = push_ctxt("trans_adt"); let _icx = push_ctxt("trans_adt");
let mut bcx = bcx; let mut bcx = bcx;
let addr = match dest { let addr = match dest {
@ -1349,18 +1389,23 @@ fn trans_adt(bcx: @Block, repr: &adt::Repr, discr: ty::Disr,
} }
fn trans_immediate_lit(bcx: @Block, expr: &ast::Expr, fn trans_immediate_lit<'a>(
lit: ast::lit) -> DatumBlock { bcx: &'a Block<'a>,
expr: &ast::Expr,
lit: ast::lit)
-> DatumBlock<'a> {
// must not be a string constant, that is a RvalueDpsExpr // must not be a string constant, that is a RvalueDpsExpr
let _icx = push_ctxt("trans_immediate_lit"); let _icx = push_ctxt("trans_immediate_lit");
let ty = expr_ty(bcx, expr); let ty = expr_ty(bcx, expr);
immediate_rvalue_bcx(bcx, consts::const_lit(bcx.ccx(), expr, lit), ty) immediate_rvalue_bcx(bcx, consts::const_lit(bcx.ccx(), expr, lit), ty)
} }
fn trans_unary_datum(bcx: @Block, fn trans_unary_datum<'a>(
bcx: &'a Block<'a>,
un_expr: &ast::Expr, un_expr: &ast::Expr,
op: ast::UnOp, op: ast::UnOp,
sub_expr: &ast::Expr) -> DatumBlock { sub_expr: &ast::Expr)
-> DatumBlock<'a> {
let _icx = push_ctxt("trans_unary_datum"); let _icx = push_ctxt("trans_unary_datum");
// if deref, would be LvalueExpr // if deref, would be LvalueExpr
@ -1419,11 +1464,13 @@ fn trans_unary_datum(bcx: @Block,
} }
}; };
fn trans_boxed_expr(bcx: @Block, fn trans_boxed_expr<'a>(
bcx: &'a Block<'a>,
box_ty: ty::t, box_ty: ty::t,
contents: &ast::Expr, contents: &ast::Expr,
contents_ty: ty::t, contents_ty: ty::t,
heap: heap) -> DatumBlock { heap: heap)
-> DatumBlock<'a> {
let _icx = push_ctxt("trans_boxed_expr"); let _icx = push_ctxt("trans_boxed_expr");
if heap == heap_exchange { if heap == heap_exchange {
let llty = type_of::type_of(bcx.ccx(), contents_ty); let llty = type_of::type_of(bcx.ccx(), contents_ty);
@ -1448,8 +1495,11 @@ fn trans_unary_datum(bcx: @Block,
} }
} }
fn trans_addr_of(bcx: @Block, expr: &ast::Expr, fn trans_addr_of<'a>(
subexpr: &ast::Expr) -> DatumBlock { bcx: &'a Block<'a>,
expr: &ast::Expr,
subexpr: &ast::Expr)
-> DatumBlock<'a> {
let _icx = push_ctxt("trans_addr_of"); let _icx = push_ctxt("trans_addr_of");
let mut bcx = bcx; let mut bcx = bcx;
let sub_datum = unpack_datum!(bcx, trans_to_datum(bcx, subexpr)); let sub_datum = unpack_datum!(bcx, trans_to_datum(bcx, subexpr));
@ -1459,13 +1509,14 @@ fn trans_addr_of(bcx: @Block, expr: &ast::Expr,
// Important to get types for both lhs and rhs, because one might be _|_ // Important to get types for both lhs and rhs, because one might be _|_
// and the other not. // and the other not.
fn trans_eager_binop(bcx: @Block, fn trans_eager_binop<'a>(
bcx: &'a Block<'a>,
binop_expr: &ast::Expr, binop_expr: &ast::Expr,
binop_ty: ty::t, binop_ty: ty::t,
op: ast::BinOp, op: ast::BinOp,
lhs_datum: &Datum, lhs_datum: &Datum,
rhs_datum: &Datum) rhs_datum: &Datum)
-> DatumBlock { -> DatumBlock<'a> {
let _icx = push_ctxt("trans_eager_binop"); let _icx = push_ctxt("trans_eager_binop");
let lhs = lhs_datum.to_appropriate_llval(bcx); let lhs = lhs_datum.to_appropriate_llval(bcx);
@ -1560,13 +1611,18 @@ fn trans_eager_binop(bcx: @Block,
} }
// refinement types would obviate the need for this // refinement types would obviate the need for this
enum lazy_binop_ty { lazy_and, lazy_or } enum lazy_binop_ty {
lazy_and,
lazy_or,
}
fn trans_lazy_binop(bcx: @Block, fn trans_lazy_binop<'a>(
bcx: &'a Block<'a>,
binop_expr: &ast::Expr, binop_expr: &ast::Expr,
op: lazy_binop_ty, op: lazy_binop_ty,
a: &ast::Expr, a: &ast::Expr,
b: &ast::Expr) -> DatumBlock { b: &ast::Expr)
-> DatumBlock<'a> {
let _icx = push_ctxt("trans_lazy_binop"); let _icx = push_ctxt("trans_lazy_binop");
let binop_ty = expr_ty(bcx, binop_expr); let binop_ty = expr_ty(bcx, binop_expr);
let bcx = bcx; let bcx = bcx;
@ -1607,12 +1663,13 @@ fn trans_lazy_binop(bcx: @Block,
return immediate_rvalue_bcx(join, phi, binop_ty); return immediate_rvalue_bcx(join, phi, binop_ty);
} }
fn trans_binary(bcx: @Block, fn trans_binary<'a>(
bcx: &'a Block<'a>,
binop_expr: &ast::Expr, binop_expr: &ast::Expr,
op: ast::BinOp, op: ast::BinOp,
lhs: &ast::Expr, lhs: &ast::Expr,
rhs: &ast::Expr) -> DatumBlock rhs: &ast::Expr)
{ -> DatumBlock<'a> {
let _icx = push_ctxt("trans_binary"); let _icx = push_ctxt("trans_binary");
match op { match op {
@ -1633,14 +1690,15 @@ fn trans_binary(bcx: @Block,
} }
} }
fn trans_overloaded_op(bcx: @Block, fn trans_overloaded_op<'a>(
bcx: &'a Block<'a>,
expr: &ast::Expr, expr: &ast::Expr,
callee_id: ast::NodeId, callee_id: ast::NodeId,
rcvr: &ast::Expr, rcvr: &ast::Expr,
args: ~[@ast::Expr], args: ~[@ast::Expr],
ret_ty: ty::t, ret_ty: ty::t,
dest: Dest) dest: Dest)
-> @Block { -> &'a Block<'a> {
let origin = { let origin = {
let method_map = bcx.ccx().maps.method_map.borrow(); let method_map = bcx.ccx().maps.method_map.borrow();
method_map.get().get_copy(&expr.id) method_map.get().get_copy(&expr.id)
@ -1661,8 +1719,12 @@ fn trans_overloaded_op(bcx: @Block,
DoAutorefArg).bcx DoAutorefArg).bcx
} }
fn int_cast(bcx: @Block, lldsttype: Type, llsrctype: Type, fn int_cast(bcx: &Block,
llsrc: ValueRef, signed: bool) -> ValueRef { lldsttype: Type,
llsrctype: Type,
llsrc: ValueRef,
signed: bool)
-> ValueRef {
let _icx = push_ctxt("int_cast"); let _icx = push_ctxt("int_cast");
unsafe { unsafe {
let srcsz = llvm::LLVMGetIntTypeWidth(llsrctype.to_ref()); let srcsz = llvm::LLVMGetIntTypeWidth(llsrctype.to_ref());
@ -1679,8 +1741,11 @@ fn int_cast(bcx: @Block, lldsttype: Type, llsrctype: Type,
} }
} }
fn float_cast(bcx: @Block, lldsttype: Type, llsrctype: Type, fn float_cast(bcx: &Block,
llsrc: ValueRef) -> ValueRef { lldsttype: Type,
llsrctype: Type,
llsrc: ValueRef)
-> ValueRef {
let _icx = push_ctxt("float_cast"); let _icx = push_ctxt("float_cast");
let srcsz = llsrctype.float_width(); let srcsz = llsrctype.float_width();
let dstsz = lldsttype.float_width(); let dstsz = lldsttype.float_width();
@ -1715,8 +1780,8 @@ pub fn cast_type_kind(t: ty::t) -> cast_kind {
} }
} }
fn trans_imm_cast(bcx: @Block, expr: &ast::Expr, fn trans_imm_cast<'a>(bcx: &'a Block<'a>, expr: &ast::Expr, id: ast::NodeId)
id: ast::NodeId) -> DatumBlock { -> DatumBlock<'a> {
let _icx = push_ctxt("trans_cast"); let _icx = push_ctxt("trans_cast");
let ccx = bcx.ccx(); let ccx = bcx.ccx();
@ -1790,13 +1855,14 @@ fn trans_imm_cast(bcx: @Block, expr: &ast::Expr,
return immediate_rvalue_bcx(bcx, newval, t_out); return immediate_rvalue_bcx(bcx, newval, t_out);
} }
fn trans_assign_op(bcx: @Block, fn trans_assign_op<'a>(
bcx: &'a Block<'a>,
expr: &ast::Expr, expr: &ast::Expr,
callee_id: ast::NodeId, callee_id: ast::NodeId,
op: ast::BinOp, op: ast::BinOp,
dst: &ast::Expr, dst: &ast::Expr,
src: @ast::Expr) -> @Block src: @ast::Expr)
{ -> &'a Block<'a> {
let _icx = push_ctxt("trans_assign_op"); let _icx = push_ctxt("trans_assign_op");
let mut bcx = bcx; let mut bcx = bcx;
@ -1835,7 +1901,7 @@ fn trans_assign_op(bcx: @Block,
return result_datum.copy_to_datum(bcx, DROP_EXISTING, dst_datum); return result_datum.copy_to_datum(bcx, DROP_EXISTING, dst_datum);
} }
pub fn trans_log_level(bcx: @Block) -> DatumBlock { pub fn trans_log_level<'a>(bcx: &'a Block<'a>) -> DatumBlock<'a> {
let _icx = push_ctxt("trans_log_level"); let _icx = push_ctxt("trans_log_level");
let ccx = bcx.ccx(); let ccx = bcx.ccx();
@ -1891,3 +1957,4 @@ pub fn trans_log_level(bcx: @Block) -> DatumBlock {
return immediate_rvalue_bcx(bcx, Load(bcx, global), ty::mk_u32()); return immediate_rvalue_bcx(bcx, Load(bcx, global), ty::mk_u32());
} }

View File

@ -161,12 +161,14 @@ pub fn register_foreign_item_fn(ccx: @CrateContext,
return llfn; return llfn;
} }
pub fn trans_native_call(bcx: @Block, pub fn trans_native_call<'a>(
bcx: &'a Block<'a>,
callee_ty: ty::t, callee_ty: ty::t,
llfn: ValueRef, llfn: ValueRef,
llretptr: ValueRef, llretptr: ValueRef,
llargs_rust: &[ValueRef], llargs_rust: &[ValueRef],
passed_arg_tys: ~[ty::t]) -> @Block { passed_arg_tys: ~[ty::t])
-> &'a Block<'a> {
/*! /*!
* Prepares a call to a native function. This requires adapting * Prepares a call to a native function. This requires adapting
* from the Rust argument passing rules to the native rules. * from the Rust argument passing rules to the native rules.

View File

@ -41,7 +41,7 @@ use std::cell::Cell;
use std::libc::c_uint; use std::libc::c_uint;
use syntax::ast; use syntax::ast;
pub fn trans_free(cx: @Block, v: ValueRef) -> @Block { pub fn trans_free<'a>(cx: &'a Block<'a>, v: ValueRef) -> &'a Block<'a> {
let _icx = push_ctxt("trans_free"); let _icx = push_ctxt("trans_free");
callee::trans_lang_call(cx, callee::trans_lang_call(cx,
langcall(cx, None, "", FreeFnLangItem), langcall(cx, None, "", FreeFnLangItem),
@ -49,7 +49,8 @@ pub fn trans_free(cx: @Block, v: ValueRef) -> @Block {
Some(expr::Ignore)).bcx Some(expr::Ignore)).bcx
} }
pub fn trans_exchange_free(cx: @Block, v: ValueRef) -> @Block { pub fn trans_exchange_free<'a>(cx: &'a Block<'a>, v: ValueRef)
-> &'a Block<'a> {
let _icx = push_ctxt("trans_exchange_free"); let _icx = push_ctxt("trans_exchange_free");
callee::trans_lang_call(cx, callee::trans_lang_call(cx,
langcall(cx, None, "", ExchangeFreeFnLangItem), langcall(cx, None, "", ExchangeFreeFnLangItem),
@ -57,7 +58,8 @@ pub fn trans_exchange_free(cx: @Block, v: ValueRef) -> @Block {
Some(expr::Ignore)).bcx Some(expr::Ignore)).bcx
} }
pub fn take_ty(cx: @Block, v: ValueRef, t: ty::t) -> @Block { pub fn take_ty<'a>(cx: &'a Block<'a>, v: ValueRef, t: ty::t)
-> &'a Block<'a> {
// NB: v is an *alias* of type t here, not a direct value. // NB: v is an *alias* of type t here, not a direct value.
let _icx = push_ctxt("take_ty"); let _icx = push_ctxt("take_ty");
if ty::type_needs_drop(cx.tcx(), t) { if ty::type_needs_drop(cx.tcx(), t) {
@ -66,7 +68,8 @@ pub fn take_ty(cx: @Block, v: ValueRef, t: ty::t) -> @Block {
return cx; return cx;
} }
pub fn drop_ty(cx: @Block, v: ValueRef, t: ty::t) -> @Block { pub fn drop_ty<'a>(cx: &'a Block<'a>, v: ValueRef, t: ty::t)
-> &'a Block<'a> {
// NB: v is an *alias* of type t here, not a direct value. // NB: v is an *alias* of type t here, not a direct value.
let _icx = push_ctxt("drop_ty"); let _icx = push_ctxt("drop_ty");
if ty::type_needs_drop(cx.tcx(), t) { if ty::type_needs_drop(cx.tcx(), t) {
@ -75,14 +78,16 @@ pub fn drop_ty(cx: @Block, v: ValueRef, t: ty::t) -> @Block {
return cx; return cx;
} }
pub fn drop_ty_immediate(bcx: @Block, v: ValueRef, t: ty::t) -> @Block { pub fn drop_ty_immediate<'a>(bcx: &'a Block<'a>, v: ValueRef, t: ty::t)
-> &'a Block<'a> {
let _icx = push_ctxt("drop_ty_immediate"); let _icx = push_ctxt("drop_ty_immediate");
let vp = alloca(bcx, type_of(bcx.ccx(), t), ""); let vp = alloca(bcx, type_of(bcx.ccx(), t), "");
Store(bcx, v, vp); Store(bcx, v, vp);
drop_ty(bcx, vp, t) drop_ty(bcx, vp, t)
} }
pub fn free_ty(cx: @Block, v: ValueRef, t: ty::t) -> @Block { pub fn free_ty<'a>(cx: &'a Block<'a>, v: ValueRef, t: ty::t)
-> &'a Block<'a> {
// NB: v is an *alias* of type t here, not a direct value. // NB: v is an *alias* of type t here, not a direct value.
let _icx = push_ctxt("free_ty"); let _icx = push_ctxt("free_ty");
if ty::type_needs_drop(cx.tcx(), t) { if ty::type_needs_drop(cx.tcx(), t) {
@ -91,7 +96,8 @@ pub fn free_ty(cx: @Block, v: ValueRef, t: ty::t) -> @Block {
return cx; return cx;
} }
pub fn free_ty_immediate(bcx: @Block, v: ValueRef, t: ty::t) -> @Block { pub fn free_ty_immediate<'a>(bcx: &'a Block<'a>, v: ValueRef, t: ty::t)
-> &'a Block<'a> {
let _icx = push_ctxt("free_ty_immediate"); let _icx = push_ctxt("free_ty_immediate");
match ty::get(t).sty { match ty::get(t).sty {
ty::ty_uniq(_) | ty::ty_uniq(_) |
@ -269,7 +275,7 @@ pub fn lazily_emit_tydesc_glue(ccx: @CrateContext,
} }
// See [Note-arg-mode] // See [Note-arg-mode]
pub fn call_tydesc_glue_full(bcx: @Block, pub fn call_tydesc_glue_full(bcx: &Block,
v: ValueRef, v: ValueRef,
tydesc: ValueRef, tydesc: ValueRef,
field: uint, field: uint,
@ -328,15 +334,20 @@ pub fn call_tydesc_glue_full(bcx: @Block,
} }
// See [Note-arg-mode] // See [Note-arg-mode]
pub fn call_tydesc_glue(cx: @Block, v: ValueRef, t: ty::t, field: uint) pub fn call_tydesc_glue<'a>(
-> @Block { cx: &'a Block<'a>,
v: ValueRef,
t: ty::t,
field: uint)
-> &'a Block<'a> {
let _icx = push_ctxt("call_tydesc_glue"); let _icx = push_ctxt("call_tydesc_glue");
let ti = get_tydesc(cx.ccx(), t); let ti = get_tydesc(cx.ccx(), t);
call_tydesc_glue_full(cx, v, ti.tydesc, field, Some(ti)); call_tydesc_glue_full(cx, v, ti.tydesc, field, Some(ti));
return cx; return cx;
} }
pub fn make_visit_glue(bcx: @Block, v: ValueRef, t: ty::t) -> @Block { pub fn make_visit_glue<'a>(bcx: &'a Block<'a>, v: ValueRef, t: ty::t)
-> &'a Block<'a> {
let _icx = push_ctxt("make_visit_glue"); let _icx = push_ctxt("make_visit_glue");
with_scope(bcx, None, "visitor cleanup", |bcx| { with_scope(bcx, None, "visitor cleanup", |bcx| {
let mut bcx = bcx; let mut bcx = bcx;
@ -355,7 +366,8 @@ pub fn make_visit_glue(bcx: @Block, v: ValueRef, t: ty::t) -> @Block {
}) })
} }
pub fn make_free_glue(bcx: @Block, v: ValueRef, t: ty::t) -> @Block { pub fn make_free_glue<'a>(bcx: &'a Block<'a>, v: ValueRef, t: ty::t)
-> &'a Block<'a> {
// NB: v0 is an *alias* of type t here, not a direct value. // NB: v0 is an *alias* of type t here, not a direct value.
let _icx = push_ctxt("make_free_glue"); let _icx = push_ctxt("make_free_glue");
match ty::get(t).sty { match ty::get(t).sty {
@ -392,8 +404,14 @@ pub fn make_free_glue(bcx: @Block, v: ValueRef, t: ty::t) -> @Block {
} }
} }
pub fn trans_struct_drop_flag(bcx: @Block, t: ty::t, v0: ValueRef, dtor_did: ast::DefId, pub fn trans_struct_drop_flag<'a>(
class_did: ast::DefId, substs: &ty::substs) -> @Block { bcx: &'a Block<'a>,
t: ty::t,
v0: ValueRef,
dtor_did: ast::DefId,
class_did: ast::DefId,
substs: &ty::substs)
-> &'a Block<'a> {
let repr = adt::represent_type(bcx.ccx(), t); let repr = adt::represent_type(bcx.ccx(), t);
let drop_flag = adt::trans_drop_flag_ptr(bcx, repr, v0); let drop_flag = adt::trans_drop_flag_ptr(bcx, repr, v0);
with_cond(bcx, IsNotNull(bcx, Load(bcx, drop_flag)), |cx| { with_cond(bcx, IsNotNull(bcx, Load(bcx, drop_flag)), |cx| {
@ -401,8 +419,14 @@ pub fn trans_struct_drop_flag(bcx: @Block, t: ty::t, v0: ValueRef, dtor_did: ast
}) })
} }
pub fn trans_struct_drop(bcx: @Block, t: ty::t, v0: ValueRef, dtor_did: ast::DefId, pub fn trans_struct_drop<'a>(
class_did: ast::DefId, substs: &ty::substs) -> @Block { bcx: &'a Block<'a>,
t: ty::t,
v0: ValueRef,
dtor_did: ast::DefId,
class_did: ast::DefId,
substs: &ty::substs)
-> &'a Block<'a> {
let repr = adt::represent_type(bcx.ccx(), t); let repr = adt::represent_type(bcx.ccx(), t);
// Find and call the actual destructor // Find and call the actual destructor
@ -439,7 +463,8 @@ pub fn trans_struct_drop(bcx: @Block, t: ty::t, v0: ValueRef, dtor_did: ast::Def
}) })
} }
pub fn make_drop_glue(bcx: @Block, v0: ValueRef, t: ty::t) -> @Block { pub fn make_drop_glue<'a>(bcx: &'a Block<'a>, v0: ValueRef, t: ty::t)
-> &'a Block<'a> {
// NB: v0 is an *alias* of type t here, not a direct value. // NB: v0 is an *alias* of type t here, not a direct value.
let _icx = push_ctxt("make_drop_glue"); let _icx = push_ctxt("make_drop_glue");
let ccx = bcx.ccx(); let ccx = bcx.ccx();
@ -510,10 +535,12 @@ pub fn make_drop_glue(bcx: @Block, v0: ValueRef, t: ty::t) -> @Block {
} }
// box_ptr_ptr is optional, it is constructed if not supplied. // box_ptr_ptr is optional, it is constructed if not supplied.
pub fn decr_refcnt_maybe_free(bcx: @Block, box_ptr: ValueRef, pub fn decr_refcnt_maybe_free<'a>(
bcx: &'a Block<'a>,
box_ptr: ValueRef,
box_ptr_ptr: Option<ValueRef>, box_ptr_ptr: Option<ValueRef>,
t: ty::t) t: ty::t)
-> @Block { -> &'a Block<'a> {
let _icx = push_ctxt("decr_refcnt_maybe_free"); let _icx = push_ctxt("decr_refcnt_maybe_free");
let ccx = bcx.ccx(); let ccx = bcx.ccx();
@ -539,7 +566,8 @@ pub fn decr_refcnt_maybe_free(bcx: @Block, box_ptr: ValueRef,
} }
pub fn make_take_glue(bcx: @Block, v: ValueRef, t: ty::t) -> @Block { pub fn make_take_glue<'a>(bcx: &'a Block<'a>, v: ValueRef, t: ty::t)
-> &'a Block<'a> {
let _icx = push_ctxt("make_take_glue"); let _icx = push_ctxt("make_take_glue");
// NB: v is a *pointer* to type t here, not a direct value. // NB: v is a *pointer* to type t here, not a direct value.
match ty::get(t).sty { match ty::get(t).sty {
@ -580,7 +608,7 @@ pub fn make_take_glue(bcx: @Block, v: ValueRef, t: ty::t) -> @Block {
} }
} }
pub fn incr_refcnt_of_boxed(cx: @Block, box_ptr: ValueRef) { pub fn incr_refcnt_of_boxed(cx: &Block, box_ptr: ValueRef) {
let _icx = push_ctxt("incr_refcnt_of_boxed"); let _icx = push_ctxt("incr_refcnt_of_boxed");
let ccx = cx.ccx(); let ccx = cx.ccx();
let rc_ptr = GEPi(cx, box_ptr, [0u, abi::box_field_refcnt]); let rc_ptr = GEPi(cx, box_ptr, [0u, abi::box_field_refcnt]);
@ -644,8 +672,8 @@ pub fn declare_tydesc(ccx: &CrateContext, t: ty::t) -> @tydesc_info {
return inf; return inf;
} }
pub type glue_helper<'a> = 'a |@Block, ValueRef, ty::t| pub type glue_helper<'a> =
-> @Block; 'a |&'a Block<'a>, ValueRef, ty::t| -> &'a Block<'a>;
pub fn declare_generic_glue(ccx: &CrateContext, t: ty::t, llfnty: Type, pub fn declare_generic_glue(ccx: &CrateContext, t: ty::t, llfnty: Type,
name: &str) -> ValueRef { name: &str) -> ValueRef {
@ -663,7 +691,10 @@ pub fn make_generic_glue_inner(ccx: @CrateContext,
helper: glue_helper) helper: glue_helper)
-> ValueRef { -> ValueRef {
let _icx = push_ctxt("make_generic_glue_inner"); let _icx = push_ctxt("make_generic_glue_inner");
let fcx = new_fn_ctxt(ccx, ~[], llfn, ty::mk_nil(), None); let fcx = new_fn_ctxt(ccx, ~[], llfn, ty::mk_nil(), None);
init_function(&fcx, false, ty::mk_nil(), None, None);
lib::llvm::SetLinkage(llfn, lib::llvm::InternalLinkage); lib::llvm::SetLinkage(llfn, lib::llvm::InternalLinkage);
ccx.stats.n_glues_created.set(ccx.stats.n_glues_created.get() + 1u); ccx.stats.n_glues_created.set(ccx.stats.n_glues_created.get() + 1u);
// All glue functions take values passed *by alias*; this is a // All glue functions take values passed *by alias*; this is a
@ -679,7 +710,7 @@ pub fn make_generic_glue_inner(ccx: @CrateContext,
let llrawptr0 = unsafe { llvm::LLVMGetParam(llfn, rawptr0_arg as c_uint) }; let llrawptr0 = unsafe { llvm::LLVMGetParam(llfn, rawptr0_arg as c_uint) };
let bcx = helper(bcx, llrawptr0, t); let bcx = helper(bcx, llrawptr0, t);
finish_fn(fcx, bcx); finish_fn(&fcx, bcx);
return llfn; return llfn;
} }

View File

@ -38,7 +38,7 @@ pub fn trans_intrinsic(ccx: @CrateContext,
ref_id: Option<ast::NodeId>) { ref_id: Option<ast::NodeId>) {
debug!("trans_intrinsic(item.ident={})", ccx.sess.str_of(item.ident)); debug!("trans_intrinsic(item.ident={})", ccx.sess.str_of(item.ident));
fn simple_llvm_intrinsic(bcx: @Block, name: &'static str, num_args: uint) { fn simple_llvm_intrinsic(bcx: &Block, name: &'static str, num_args: uint) {
assert!(num_args <= 4); assert!(num_args <= 4);
let mut args = [0 as ValueRef, ..4]; let mut args = [0 as ValueRef, ..4];
let first_real_arg = bcx.fcx.arg_pos(0u); let first_real_arg = bcx.fcx.arg_pos(0u);
@ -50,7 +50,7 @@ pub fn trans_intrinsic(ccx: @CrateContext,
Ret(bcx, llcall); Ret(bcx, llcall);
} }
fn with_overflow_instrinsic(bcx: @Block, name: &'static str, t: ty::t) { fn with_overflow_instrinsic(bcx: &Block, name: &'static str, t: ty::t) {
let first_real_arg = bcx.fcx.arg_pos(0u); let first_real_arg = bcx.fcx.arg_pos(0u);
let a = get_param(bcx.fcx.llfn, first_real_arg); let a = get_param(bcx.fcx.llfn, first_real_arg);
let b = get_param(bcx.fcx.llfn, first_real_arg + 1); let b = get_param(bcx.fcx.llfn, first_real_arg + 1);
@ -73,7 +73,7 @@ pub fn trans_intrinsic(ccx: @CrateContext,
} }
} }
fn volatile_load_intrinsic(bcx: @Block) { fn volatile_load_intrinsic(bcx: &Block) {
let first_real_arg = bcx.fcx.arg_pos(0u); let first_real_arg = bcx.fcx.arg_pos(0u);
let src = get_param(bcx.fcx.llfn, first_real_arg); let src = get_param(bcx.fcx.llfn, first_real_arg);
@ -81,7 +81,7 @@ pub fn trans_intrinsic(ccx: @CrateContext,
Ret(bcx, val); Ret(bcx, val);
} }
fn volatile_store_intrinsic(bcx: @Block) { fn volatile_store_intrinsic(bcx: &Block) {
let first_real_arg = bcx.fcx.arg_pos(0u); let first_real_arg = bcx.fcx.arg_pos(0u);
let dst = get_param(bcx.fcx.llfn, first_real_arg); let dst = get_param(bcx.fcx.llfn, first_real_arg);
let val = get_param(bcx.fcx.llfn, first_real_arg + 1); let val = get_param(bcx.fcx.llfn, first_real_arg + 1);
@ -90,7 +90,7 @@ pub fn trans_intrinsic(ccx: @CrateContext,
RetVoid(bcx); RetVoid(bcx);
} }
fn copy_intrinsic(bcx: @Block, allow_overlap: bool, tp_ty: ty::t) { fn copy_intrinsic(bcx: &Block, allow_overlap: bool, tp_ty: ty::t) {
let ccx = bcx.ccx(); let ccx = bcx.ccx();
let lltp_ty = type_of::type_of(ccx, tp_ty); let lltp_ty = type_of::type_of(ccx, tp_ty);
let align = C_i32(machine::llalign_of_min(ccx, lltp_ty) as i32); let align = C_i32(machine::llalign_of_min(ccx, lltp_ty) as i32);
@ -121,7 +121,7 @@ pub fn trans_intrinsic(ccx: @CrateContext,
RetVoid(bcx); RetVoid(bcx);
} }
fn memset_intrinsic(bcx: @Block, tp_ty: ty::t) { fn memset_intrinsic(bcx: &Block, tp_ty: ty::t) {
let ccx = bcx.ccx(); let ccx = bcx.ccx();
let lltp_ty = type_of::type_of(ccx, tp_ty); let lltp_ty = type_of::type_of(ccx, tp_ty);
let align = C_i32(machine::llalign_of_min(ccx, lltp_ty) as i32); let align = C_i32(machine::llalign_of_min(ccx, lltp_ty) as i32);
@ -143,7 +143,7 @@ pub fn trans_intrinsic(ccx: @CrateContext,
RetVoid(bcx); RetVoid(bcx);
} }
fn count_zeros_intrinsic(bcx: @Block, name: &'static str) { fn count_zeros_intrinsic(bcx: &Block, name: &'static str) {
let x = get_param(bcx.fcx.llfn, bcx.fcx.arg_pos(0u)); let x = get_param(bcx.fcx.llfn, bcx.fcx.arg_pos(0u));
let y = C_i1(false); let y = C_i1(false);
let llfn = bcx.ccx().intrinsics.get_copy(&name); let llfn = bcx.ccx().intrinsics.get_copy(&name);
@ -158,10 +158,9 @@ pub fn trans_intrinsic(ccx: @CrateContext,
decl, decl,
item.id, item.id,
output_type, output_type,
true,
Some(substs), Some(substs),
None,
Some(item.span)); Some(item.span));
init_function(&fcx, true, output_type, Some(substs), None);
set_always_inline(fcx.llfn); set_always_inline(fcx.llfn);

View File

@ -138,10 +138,12 @@ pub fn trans_method(ccx: @CrateContext,
[]); []);
} }
pub fn trans_self_arg(bcx: @Block, pub fn trans_self_arg<'a>(
bcx: &'a Block<'a>,
base: &ast::Expr, base: &ast::Expr,
temp_cleanups: &mut ~[ValueRef], temp_cleanups: &mut ~[ValueRef],
mentry: typeck::method_map_entry) -> Result { mentry: typeck::method_map_entry)
-> Result<'a> {
let _icx = push_ctxt("impl::trans_self_arg"); let _icx = push_ctxt("impl::trans_self_arg");
// self is passed as an opaque box in the environment slot // self is passed as an opaque box in the environment slot
@ -154,11 +156,12 @@ pub fn trans_self_arg(bcx: @Block,
DontAutorefArg) DontAutorefArg)
} }
pub fn trans_method_callee(bcx: @Block, pub fn trans_method_callee<'a>(
bcx: &'a Block<'a>,
callee_id: ast::NodeId, callee_id: ast::NodeId,
this: &ast::Expr, this: &ast::Expr,
mentry: typeck::method_map_entry) mentry: typeck::method_map_entry)
-> Callee { -> Callee<'a> {
let _icx = push_ctxt("impl::trans_method_callee"); let _icx = push_ctxt("impl::trans_method_callee");
debug!("trans_method_callee(callee_id={:?}, this={}, mentry={})", debug!("trans_method_callee(callee_id={:?}, this={}, mentry={})",
@ -212,7 +215,7 @@ pub fn trans_method_callee(bcx: @Block,
} }
} }
pub fn trans_static_method_callee(bcx: @Block, pub fn trans_static_method_callee(bcx: &Block,
method_id: ast::DefId, method_id: ast::DefId,
trait_id: ast::DefId, trait_id: ast::DefId,
callee_id: ast::NodeId) callee_id: ast::NodeId)
@ -322,14 +325,15 @@ pub fn method_with_name(ccx: &CrateContext,
meth.def_id meth.def_id
} }
pub fn trans_monomorphized_callee(bcx: @Block, pub fn trans_monomorphized_callee<'a>(
bcx: &'a Block<'a>,
callee_id: ast::NodeId, callee_id: ast::NodeId,
base: &ast::Expr, base: &ast::Expr,
mentry: typeck::method_map_entry, mentry: typeck::method_map_entry,
trait_id: ast::DefId, trait_id: ast::DefId,
n_method: uint, n_method: uint,
vtbl: typeck::vtable_origin) vtbl: typeck::vtable_origin)
-> Callee { -> Callee<'a> {
let _icx = push_ctxt("impl::trans_monomorphized_callee"); let _icx = push_ctxt("impl::trans_monomorphized_callee");
return match vtbl { return match vtbl {
typeck::vtable_static(impl_did, ref rcvr_substs, rcvr_origins) => { typeck::vtable_static(impl_did, ref rcvr_substs, rcvr_origins) => {
@ -379,7 +383,7 @@ pub fn trans_monomorphized_callee(bcx: @Block,
} }
pub fn combine_impl_and_methods_tps(bcx: @Block, pub fn combine_impl_and_methods_tps(bcx: &Block,
mth_did: ast::DefId, mth_did: ast::DefId,
callee_id: ast::NodeId, callee_id: ast::NodeId,
rcvr_substs: &[ty::t], rcvr_substs: &[ty::t],
@ -428,11 +432,12 @@ pub fn combine_impl_and_methods_tps(bcx: @Block,
return (ty_substs, vtables); return (ty_substs, vtables);
} }
pub fn trans_trait_callee(bcx: @Block, pub fn trans_trait_callee<'a>(
bcx: &'a Block<'a>,
callee_id: ast::NodeId, callee_id: ast::NodeId,
n_method: uint, n_method: uint,
self_expr: &ast::Expr) self_expr: &ast::Expr)
-> Callee { -> Callee<'a> {
/*! /*!
* Create a method callee where the method is coming from a trait * Create a method callee where the method is coming from a trait
* object (e.g., @Trait type). In this case, we must pull the fn * object (e.g., @Trait type). In this case, we must pull the fn
@ -470,12 +475,13 @@ pub fn trans_trait_callee(bcx: @Block,
Some(self_scratch.val)) Some(self_scratch.val))
} }
pub fn trans_trait_callee_from_llval(bcx: @Block, pub fn trans_trait_callee_from_llval<'a>(
bcx: &'a Block<'a>,
callee_ty: ty::t, callee_ty: ty::t,
n_method: uint, n_method: uint,
llpair: ValueRef, llpair: ValueRef,
temp_cleanup: Option<ValueRef>) temp_cleanup: Option<ValueRef>)
-> Callee { -> Callee<'a> {
/*! /*!
* Same as `trans_trait_callee()` above, except that it is given * Same as `trans_trait_callee()` above, except that it is given
* a by-ref pointer to the object pair. * a by-ref pointer to the object pair.
@ -541,7 +547,7 @@ pub fn vtable_id(ccx: @CrateContext,
/// Creates a returns a dynamic vtable for the given type and vtable origin. /// Creates a returns a dynamic vtable for the given type and vtable origin.
/// This is used only for objects. /// This is used only for objects.
pub fn get_vtable(bcx: @Block, pub fn get_vtable(bcx: &Block,
self_ty: ty::t, self_ty: ty::t,
origins: typeck::vtable_param_res) origins: typeck::vtable_param_res)
-> ValueRef { -> ValueRef {
@ -604,7 +610,7 @@ pub fn make_vtable(ccx: &CrateContext,
} }
} }
fn emit_vtable_methods(bcx: @Block, fn emit_vtable_methods(bcx: &Block,
impl_id: ast::DefId, impl_id: ast::DefId,
substs: &[ty::t], substs: &[ty::t],
vtables: typeck::vtable_res) vtables: typeck::vtable_res)
@ -642,13 +648,14 @@ fn emit_vtable_methods(bcx: @Block,
}) })
} }
pub fn trans_trait_cast(bcx: @Block, pub fn trans_trait_cast<'a>(
bcx: &'a Block<'a>,
val: &ast::Expr, val: &ast::Expr,
id: ast::NodeId, id: ast::NodeId,
dest: expr::Dest, dest: expr::Dest,
_store: ty::TraitStore, _store: ty::TraitStore,
do_adjustments: bool) do_adjustments: bool)
-> @Block { -> &'a Block<'a> {
let mut bcx = bcx; let mut bcx = bcx;
let _icx = push_ctxt("impl::trans_cast"); let _icx = push_ctxt("impl::trans_cast");

View File

@ -34,15 +34,15 @@ use syntax::parse::token::special_idents;
use middle::trans::type_::Type; use middle::trans::type_::Type;
pub struct Reflector { pub struct Reflector<'a> {
visitor_val: ValueRef, visitor_val: ValueRef,
visitor_methods: @~[@ty::Method], visitor_methods: @~[@ty::Method],
final_bcx: @Block, final_bcx: &'a Block<'a>,
tydesc_ty: Type, tydesc_ty: Type,
bcx: @Block bcx: &'a Block<'a>
} }
impl Reflector { impl<'a> Reflector<'a> {
pub fn c_uint(&mut self, u: uint) -> ValueRef { pub fn c_uint(&mut self, u: uint) -> ValueRef {
C_uint(self.bcx.ccx(), u) C_uint(self.bcx.ccx(), u)
} }
@ -301,6 +301,8 @@ impl Reflector {
llfdecl, llfdecl,
ty::mk_u64(), ty::mk_u64(),
None); None);
init_function(&fcx, false, ty::mk_u64(), None, None);
let arg = unsafe { let arg = unsafe {
// //
// we know the return type of llfdecl is an int here, so // we know the return type of llfdecl is an int here, so
@ -317,7 +319,7 @@ impl Reflector {
Some(llreturn) => cleanup_and_Br(bcx, bcx, llreturn), Some(llreturn) => cleanup_and_Br(bcx, bcx, llreturn),
None => bcx = cleanup_block(bcx, Some(bcx.llbb)) None => bcx = cleanup_block(bcx, Some(bcx.llbb))
}; };
finish_fn(fcx, bcx); finish_fn(&fcx, bcx);
llfdecl llfdecl
}; };
@ -385,11 +387,12 @@ impl Reflector {
} }
// Emit a sequence of calls to visit_ty::visit_foo // Emit a sequence of calls to visit_ty::visit_foo
pub fn emit_calls_to_trait_visit_ty(bcx: @Block, pub fn emit_calls_to_trait_visit_ty<'a>(
bcx: &'a Block<'a>,
t: ty::t, t: ty::t,
visitor_val: ValueRef, visitor_val: ValueRef,
visitor_trait_id: DefId) visitor_trait_id: DefId)
-> @Block { -> &'a Block<'a> {
let final = sub_block(bcx, "final"); let final = sub_block(bcx, "final");
let tydesc_ty = ty::get_tydesc_ty(bcx.ccx().tcx).unwrap(); let tydesc_ty = ty::get_tydesc_ty(bcx.ccx().tcx).unwrap();
let tydesc_ty = type_of(bcx.ccx(), tydesc_ty); let tydesc_ty = type_of(bcx.ccx(), tydesc_ty);

View File

@ -53,18 +53,20 @@ pub fn expand_boxed_vec_ty(tcx: ty::ctxt, t: ty::t) -> ty::t {
} }
} }
pub fn get_fill(bcx: @Block, vptr: ValueRef) -> ValueRef { pub fn get_fill(bcx: &Block, vptr: ValueRef) -> ValueRef {
let _icx = push_ctxt("tvec::get_fill"); let _icx = push_ctxt("tvec::get_fill");
Load(bcx, GEPi(bcx, vptr, [0u, abi::vec_elt_fill])) Load(bcx, GEPi(bcx, vptr, [0u, abi::vec_elt_fill]))
} }
pub fn set_fill(bcx: @Block, vptr: ValueRef, fill: ValueRef) {
pub fn set_fill(bcx: &Block, vptr: ValueRef, fill: ValueRef) {
Store(bcx, fill, GEPi(bcx, vptr, [0u, abi::vec_elt_fill])); Store(bcx, fill, GEPi(bcx, vptr, [0u, abi::vec_elt_fill]));
} }
pub fn get_alloc(bcx: @Block, vptr: ValueRef) -> ValueRef {
pub fn get_alloc(bcx: &Block, vptr: ValueRef) -> ValueRef {
Load(bcx, GEPi(bcx, vptr, [0u, abi::vec_elt_alloc])) Load(bcx, GEPi(bcx, vptr, [0u, abi::vec_elt_alloc]))
} }
pub fn get_bodyptr(bcx: @Block, vptr: ValueRef, t: ty::t) -> ValueRef { pub fn get_bodyptr(bcx: &Block, vptr: ValueRef, t: ty::t) -> ValueRef {
if ty::type_contents(bcx.tcx(), t).owns_managed() { if ty::type_contents(bcx.tcx(), t).owns_managed() {
GEPi(bcx, vptr, [0u, abi::box_field_body]) GEPi(bcx, vptr, [0u, abi::box_field_body])
} else { } else {
@ -72,20 +74,25 @@ pub fn get_bodyptr(bcx: @Block, vptr: ValueRef, t: ty::t) -> ValueRef {
} }
} }
pub fn get_dataptr(bcx: @Block, vptr: ValueRef) -> ValueRef { pub fn get_dataptr(bcx: &Block, vptr: ValueRef) -> ValueRef {
let _icx = push_ctxt("tvec::get_dataptr"); let _icx = push_ctxt("tvec::get_dataptr");
GEPi(bcx, vptr, [0u, abi::vec_elt_elems, 0u]) GEPi(bcx, vptr, [0u, abi::vec_elt_elems, 0u])
} }
pub fn pointer_add_byte(bcx: @Block, ptr: ValueRef, bytes: ValueRef) -> ValueRef { pub fn pointer_add_byte(bcx: &Block, ptr: ValueRef, bytes: ValueRef) -> ValueRef {
let _icx = push_ctxt("tvec::pointer_add_byte"); let _icx = push_ctxt("tvec::pointer_add_byte");
let old_ty = val_ty(ptr); let old_ty = val_ty(ptr);
let bptr = PointerCast(bcx, ptr, Type::i8p()); let bptr = PointerCast(bcx, ptr, Type::i8p());
return PointerCast(bcx, InBoundsGEP(bcx, bptr, [bytes]), old_ty); return PointerCast(bcx, InBoundsGEP(bcx, bptr, [bytes]), old_ty);
} }
pub fn alloc_raw(bcx: @Block, unit_ty: ty::t, pub fn alloc_raw<'a>(
fill: ValueRef, alloc: ValueRef, heap: heap) -> Result { bcx: &'a Block<'a>,
unit_ty: ty::t,
fill: ValueRef,
alloc: ValueRef,
heap: heap)
-> Result<'a> {
let _icx = push_ctxt("tvec::alloc_uniq"); let _icx = push_ctxt("tvec::alloc_uniq");
let ccx = bcx.ccx(); let ccx = bcx.ccx();
@ -107,16 +114,21 @@ pub fn alloc_raw(bcx: @Block, unit_ty: ty::t,
} }
} }
pub fn alloc_uniq_raw(bcx: @Block, unit_ty: ty::t, pub fn alloc_uniq_raw<'a>(
fill: ValueRef, alloc: ValueRef) -> Result { bcx: &'a Block<'a>,
unit_ty: ty::t,
fill: ValueRef,
alloc: ValueRef)
-> Result<'a> {
alloc_raw(bcx, unit_ty, fill, alloc, base::heap_for_unique(bcx, unit_ty)) alloc_raw(bcx, unit_ty, fill, alloc, base::heap_for_unique(bcx, unit_ty))
} }
pub fn alloc_vec(bcx: @Block, pub fn alloc_vec<'a>(
bcx: &'a Block<'a>,
unit_ty: ty::t, unit_ty: ty::t,
elts: uint, elts: uint,
heap: heap) heap: heap)
-> Result { -> Result<'a> {
let _icx = push_ctxt("tvec::alloc_uniq"); let _icx = push_ctxt("tvec::alloc_uniq");
let ccx = bcx.ccx(); let ccx = bcx.ccx();
let llunitty = type_of::type_of(ccx, unit_ty); let llunitty = type_of::type_of(ccx, unit_ty);
@ -130,8 +142,11 @@ pub fn alloc_vec(bcx: @Block,
return rslt(bcx, vptr); return rslt(bcx, vptr);
} }
pub fn make_drop_glue_unboxed(bcx: @Block, vptr: ValueRef, vec_ty: ty::t) -> pub fn make_drop_glue_unboxed<'a>(
@Block { bcx: &'a Block<'a>,
vptr: ValueRef,
vec_ty: ty::t)
-> &'a Block<'a> {
let _icx = push_ctxt("tvec::make_drop_glue_unboxed"); let _icx = push_ctxt("tvec::make_drop_glue_unboxed");
let tcx = bcx.tcx(); let tcx = bcx.tcx();
let unit_ty = ty::sequence_element_type(tcx, vec_ty); let unit_ty = ty::sequence_element_type(tcx, vec_ty);
@ -160,11 +175,12 @@ impl VecTypes {
} }
} }
pub fn trans_fixed_vstore(bcx: @Block, pub fn trans_fixed_vstore<'a>(
bcx: &'a Block<'a>,
vstore_expr: &ast::Expr, vstore_expr: &ast::Expr,
content_expr: &ast::Expr, content_expr: &ast::Expr,
dest: expr::Dest) dest: expr::Dest)
-> @Block { -> &'a Block<'a> {
//! //!
// //
// [...] allocates a fixed-size array and moves it around "by value". // [...] allocates a fixed-size array and moves it around "by value".
@ -189,11 +205,12 @@ pub fn trans_fixed_vstore(bcx: @Block,
}; };
} }
pub fn trans_slice_vstore(bcx: @Block, pub fn trans_slice_vstore<'a>(
bcx: &'a Block<'a>,
vstore_expr: &ast::Expr, vstore_expr: &ast::Expr,
content_expr: &ast::Expr, content_expr: &ast::Expr,
dest: expr::Dest) dest: expr::Dest)
-> @Block { -> &'a Block<'a> {
//! //!
// //
// &[...] allocates memory on the stack and writes the values into it, // &[...] allocates memory on the stack and writes the values into it,
@ -247,11 +264,12 @@ pub fn trans_slice_vstore(bcx: @Block,
return bcx; return bcx;
} }
pub fn trans_lit_str(bcx: @Block, pub fn trans_lit_str<'a>(
bcx: &'a Block<'a>,
lit_expr: &ast::Expr, lit_expr: &ast::Expr,
str_lit: @str, str_lit: @str,
dest: Dest) dest: Dest)
-> @Block { -> &'a Block<'a> {
//! //!
// //
// Literal strings translate to slices into static memory. This is // Literal strings translate to slices into static memory. This is
@ -282,8 +300,12 @@ pub fn trans_lit_str(bcx: @Block,
} }
pub fn trans_uniq_or_managed_vstore(bcx: @Block, heap: heap, vstore_expr: &ast::Expr, pub fn trans_uniq_or_managed_vstore<'a>(
content_expr: &ast::Expr) -> DatumBlock { bcx: &'a Block<'a>,
heap: heap,
vstore_expr: &ast::Expr,
content_expr: &ast::Expr)
-> DatumBlock<'a> {
//! //!
// //
// @[...] or ~[...] (also @"..." or ~"...") allocate boxes in the // @[...] or ~[...] (also @"..." or ~"...") allocate boxes in the
@ -343,12 +365,13 @@ pub fn trans_uniq_or_managed_vstore(bcx: @Block, heap: heap, vstore_expr: &ast::
return immediate_rvalue_bcx(bcx, val, vt.vec_ty); return immediate_rvalue_bcx(bcx, val, vt.vec_ty);
} }
pub fn write_content(bcx: @Block, pub fn write_content<'a>(
bcx: &'a Block<'a>,
vt: &VecTypes, vt: &VecTypes,
vstore_expr: &ast::Expr, vstore_expr: &ast::Expr,
content_expr: &ast::Expr, content_expr: &ast::Expr,
dest: Dest) dest: Dest)
-> @Block { -> &'a Block<'a> {
let _icx = push_ctxt("tvec::write_content"); let _icx = push_ctxt("tvec::write_content");
let mut bcx = bcx; let mut bcx = bcx;
@ -433,12 +456,12 @@ pub fn write_content(bcx: @Block,
} }
} }
pub fn vec_types_from_expr(bcx: @Block, vec_expr: &ast::Expr) -> VecTypes { pub fn vec_types_from_expr(bcx: &Block, vec_expr: &ast::Expr) -> VecTypes {
let vec_ty = node_id_type(bcx, vec_expr.id); let vec_ty = node_id_type(bcx, vec_expr.id);
vec_types(bcx, vec_ty) vec_types(bcx, vec_ty)
} }
pub fn vec_types(bcx: @Block, vec_ty: ty::t) -> VecTypes { pub fn vec_types(bcx: &Block, vec_ty: ty::t) -> VecTypes {
let ccx = bcx.ccx(); let ccx = bcx.ccx();
let unit_ty = ty::sequence_element_type(bcx.tcx(), vec_ty); let unit_ty = ty::sequence_element_type(bcx.tcx(), vec_ty);
let llunit_ty = type_of::type_of(ccx, unit_ty); let llunit_ty = type_of::type_of(ccx, unit_ty);
@ -452,7 +475,7 @@ pub fn vec_types(bcx: @Block, vec_ty: ty::t) -> VecTypes {
llunit_alloc_size: llunit_alloc_size} llunit_alloc_size: llunit_alloc_size}
} }
pub fn elements_required(bcx: @Block, content_expr: &ast::Expr) -> uint { pub fn elements_required(bcx: &Block, content_expr: &ast::Expr) -> uint {
//! Figure out the number of elements we need to store this content //! Figure out the number of elements we need to store this content
match content_expr.node { match content_expr.node {
@ -468,8 +491,8 @@ pub fn elements_required(bcx: @Block, content_expr: &ast::Expr) -> uint {
} }
} }
pub fn get_base_and_byte_len(bcx: @Block, llval: ValueRef, pub fn get_base_and_byte_len(bcx: &Block, llval: ValueRef, vec_ty: ty::t)
vec_ty: ty::t) -> (ValueRef, ValueRef) { -> (ValueRef, ValueRef) {
//! //!
// //
// Converts a vector into the slice pair. The vector should be stored in // Converts a vector into the slice pair. The vector should be stored in
@ -505,7 +528,8 @@ pub fn get_base_and_byte_len(bcx: @Block, llval: ValueRef,
} }
} }
pub fn get_base_and_len(bcx: @Block, llval: ValueRef, vec_ty: ty::t) -> (ValueRef, ValueRef) { pub fn get_base_and_len(bcx: &Block, llval: ValueRef, vec_ty: ty::t)
-> (ValueRef, ValueRef) {
//! //!
// //
// Converts a vector into the slice pair. The vector should be stored in // Converts a vector into the slice pair. The vector should be stored in
@ -539,15 +563,17 @@ pub fn get_base_and_len(bcx: @Block, llval: ValueRef, vec_ty: ty::t) -> (ValueRe
} }
} }
pub type iter_vec_block<'a> = 'a |@Block, ValueRef, ty::t| pub type iter_vec_block<'r,'b> =
-> @Block; 'r |&'b Block<'b>, ValueRef, ty::t| -> &'b Block<'b>;
pub fn iter_vec_loop(bcx: @Block, pub fn iter_vec_loop<'r,
'b>(
bcx: &'b Block<'b>,
data_ptr: ValueRef, data_ptr: ValueRef,
vt: &VecTypes, vt: &VecTypes,
count: ValueRef, count: ValueRef,
f: iter_vec_block f: iter_vec_block<'r,'b>)
) -> @Block { -> &'b Block<'b> {
let _icx = push_ctxt("tvec::iter_vec_loop"); let _icx = push_ctxt("tvec::iter_vec_loop");
let next_bcx = sub_block(bcx, "iter_vec_loop: while next"); let next_bcx = sub_block(bcx, "iter_vec_loop: while next");
@ -597,8 +623,14 @@ pub fn iter_vec_loop(bcx: @Block,
next_bcx next_bcx
} }
pub fn iter_vec_raw(bcx: @Block, data_ptr: ValueRef, vec_ty: ty::t, pub fn iter_vec_raw<'r,
fill: ValueRef, f: iter_vec_block) -> @Block { 'b>(
bcx: &'b Block<'b>,
data_ptr: ValueRef,
vec_ty: ty::t,
fill: ValueRef,
f: iter_vec_block<'r,'b>)
-> &'b Block<'b> {
let _icx = push_ctxt("tvec::iter_vec_raw"); let _icx = push_ctxt("tvec::iter_vec_raw");
let vt = vec_types(bcx, vec_ty); let vt = vec_types(bcx, vec_ty);
@ -632,15 +664,26 @@ pub fn iter_vec_raw(bcx: @Block, data_ptr: ValueRef, vec_ty: ty::t,
} }
} }
pub fn iter_vec_uniq(bcx: @Block, vptr: ValueRef, vec_ty: ty::t, pub fn iter_vec_uniq<'r,
fill: ValueRef, f: iter_vec_block) -> @Block { 'b>(
bcx: &'b Block<'b>,
vptr: ValueRef,
vec_ty: ty::t,
fill: ValueRef,
f: iter_vec_block<'r,'b>)
-> &'b Block<'b> {
let _icx = push_ctxt("tvec::iter_vec_uniq"); let _icx = push_ctxt("tvec::iter_vec_uniq");
let data_ptr = get_dataptr(bcx, get_bodyptr(bcx, vptr, vec_ty)); let data_ptr = get_dataptr(bcx, get_bodyptr(bcx, vptr, vec_ty));
iter_vec_raw(bcx, data_ptr, vec_ty, fill, f) iter_vec_raw(bcx, data_ptr, vec_ty, fill, f)
} }
pub fn iter_vec_unboxed(bcx: @Block, body_ptr: ValueRef, vec_ty: ty::t, pub fn iter_vec_unboxed<'r,
f: iter_vec_block) -> @Block { 'b>(
bcx: &'b Block<'b>,
body_ptr: ValueRef,
vec_ty: ty::t,
f: iter_vec_block<'r,'b>)
-> &'b Block<'b> {
let _icx = push_ctxt("tvec::iter_vec_unboxed"); let _icx = push_ctxt("tvec::iter_vec_unboxed");
let fill = get_fill(bcx, body_ptr); let fill = get_fill(bcx, body_ptr);
let dataptr = get_dataptr(bcx, body_ptr); let dataptr = get_dataptr(bcx, body_ptr);

View File

@ -17,8 +17,11 @@ use middle::trans::datum::immediate_rvalue;
use middle::trans::glue; use middle::trans::glue;
use middle::ty; use middle::ty;
pub fn make_free_glue(bcx: @Block, vptrptr: ValueRef, box_ty: ty::t) pub fn make_free_glue<'a>(
-> @Block { bcx: &'a Block<'a>,
vptrptr: ValueRef,
box_ty: ty::t)
-> &'a Block<'a> {
let _icx = push_ctxt("uniq::make_free_glue"); let _icx = push_ctxt("uniq::make_free_glue");
let box_datum = immediate_rvalue(Load(bcx, vptrptr), box_ty); let box_datum = immediate_rvalue(Load(bcx, vptrptr), box_ty);

View File

@ -22,11 +22,13 @@ use middle::trans::datum::*;
use syntax::codemap::Span; use syntax::codemap::Span;
use syntax::ast; use syntax::ast;
pub fn root_and_write_guard(datum: &Datum, pub fn root_and_write_guard<'a>(
bcx: @Block, datum: &Datum,
bcx: &'a Block<'a>,
span: Span, span: Span,
expr_id: ast::NodeId, expr_id: ast::NodeId,
derefs: uint) -> @Block { derefs: uint)
-> &'a Block<'a> {
let key = root_map_key { id: expr_id, derefs: derefs }; let key = root_map_key { id: expr_id, derefs: derefs };
debug!("write_guard::root_and_write_guard(key={:?})", key); debug!("write_guard::root_and_write_guard(key={:?})", key);
@ -41,11 +43,13 @@ pub fn root_and_write_guard(datum: &Datum,
} }
} }
fn root(datum: &Datum, fn root<'a>(
bcx: @Block, datum: &Datum,
bcx: &'a Block<'a>,
_: Span, _: Span,
root_key: root_map_key, root_key: root_map_key,
root_info: RootInfo) -> @Block { root_info: RootInfo)
-> &'a Block<'a> {
//! In some cases, borrowck will decide that an @T/@[]/@str //! In some cases, borrowck will decide that an @T/@[]/@str
//! value must be rooted for the program to be safe. In that //! value must be rooted for the program to be safe. In that
//! case, we will call this function, which will stash a copy //! case, we will call this function, which will stash a copy