Clean up some of trans using block combinators
`with_scope` and `with_cond` can be used to wrap a piece of code in a scope block, or conditionalize it on a value, without doing all the context-creation and jumping by hand. Also renames @block_ctxt to block to reduce noise.
This commit is contained in:
parent
1c1261bcb8
commit
ff42964546
12 changed files with 782 additions and 898 deletions
|
@ -224,7 +224,7 @@ fn line_from_span(cm: codemap::codemap, sp: span) -> uint {
|
||||||
codemap::lookup_char_pos(cm, sp.lo).line
|
codemap::lookup_char_pos(cm, sp.lo).line
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_block(cx: @block_ctxt) -> @metadata<block_md> {
|
fn create_block(cx: block) -> @metadata<block_md> {
|
||||||
let cache = get_cache(bcx_ccx(cx));
|
let cache = get_cache(bcx_ccx(cx));
|
||||||
let cx = cx;
|
let cx = cx;
|
||||||
while option::is_none(cx.block_span) {
|
while option::is_none(cx.block_span) {
|
||||||
|
@ -677,7 +677,7 @@ fn create_var(type_tag: int, context: ValueRef, name: str, file: ValueRef,
|
||||||
ret llmdnode(lldata);
|
ret llmdnode(lldata);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_local_var(bcx: @block_ctxt, local: @ast::local)
|
fn create_local_var(bcx: block, local: @ast::local)
|
||||||
-> @metadata<local_var_md> unsafe {
|
-> @metadata<local_var_md> unsafe {
|
||||||
let cx = bcx_ccx(bcx);
|
let cx = bcx_ccx(bcx);
|
||||||
let cache = get_cache(cx);
|
let cache = get_cache(cx);
|
||||||
|
@ -728,7 +728,7 @@ fn create_local_var(bcx: @block_ctxt, local: @ast::local)
|
||||||
ret mdval;
|
ret mdval;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_arg(bcx: @block_ctxt, arg: ast::arg, sp: span)
|
fn create_arg(bcx: block, arg: ast::arg, sp: span)
|
||||||
-> @metadata<argument_md> unsafe {
|
-> @metadata<argument_md> unsafe {
|
||||||
let fcx = bcx_fcx(bcx);
|
let fcx = bcx_fcx(bcx);
|
||||||
let cx = fcx_ccx(fcx);
|
let cx = fcx_ccx(fcx);
|
||||||
|
@ -763,7 +763,7 @@ fn create_arg(bcx: @block_ctxt, arg: ast::arg, sp: span)
|
||||||
ret mdval;
|
ret mdval;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update_source_pos(cx: @block_ctxt, s: span) {
|
fn update_source_pos(cx: block, s: span) {
|
||||||
if !bcx_ccx(cx).sess.opts.debuginfo {
|
if !bcx_ccx(cx).sess.opts.debuginfo {
|
||||||
ret;
|
ret;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,8 +3,7 @@ import lib::llvm::llvm;
|
||||||
import lib::llvm::{ValueRef, BasicBlockRef};
|
import lib::llvm::{ValueRef, BasicBlockRef};
|
||||||
import pat_util::*;
|
import pat_util::*;
|
||||||
import build::*;
|
import build::*;
|
||||||
import base::{new_sub_block_ctxt, new_scope_block_ctxt,
|
import base::*;
|
||||||
new_real_block_ctxt, load_if_immediate};
|
|
||||||
import syntax::ast;
|
import syntax::ast;
|
||||||
import syntax::ast_util;
|
import syntax::ast_util;
|
||||||
import syntax::ast_util::{dummy_sp};
|
import syntax::ast_util::{dummy_sp};
|
||||||
|
@ -38,28 +37,28 @@ enum opt_result {
|
||||||
single_result(result),
|
single_result(result),
|
||||||
range_result(result, result),
|
range_result(result, result),
|
||||||
}
|
}
|
||||||
fn trans_opt(bcx: @block_ctxt, o: opt) -> opt_result {
|
fn trans_opt(bcx: block, o: opt) -> opt_result {
|
||||||
let ccx = bcx_ccx(bcx), bcx = bcx;
|
let ccx = bcx_ccx(bcx), bcx = bcx;
|
||||||
alt o {
|
alt o {
|
||||||
lit(l) {
|
lit(l) {
|
||||||
alt l.node {
|
alt l.node {
|
||||||
ast::expr_lit(@{node: ast::lit_str(s), _}) {
|
ast::expr_lit(@{node: ast::lit_str(s), _}) {
|
||||||
let strty = ty::mk_str(bcx_tcx(bcx));
|
let strty = ty::mk_str(bcx_tcx(bcx));
|
||||||
let cell = base::empty_dest_cell();
|
let cell = empty_dest_cell();
|
||||||
bcx = tvec::trans_str(bcx, s, base::by_val(cell));
|
bcx = tvec::trans_str(bcx, s, by_val(cell));
|
||||||
add_clean_temp(bcx, *cell, strty);
|
add_clean_temp(bcx, *cell, strty);
|
||||||
ret single_result(rslt(bcx, *cell));
|
ret single_result(rslt(bcx, *cell));
|
||||||
}
|
}
|
||||||
_ {
|
_ {
|
||||||
ret single_result(
|
ret single_result(
|
||||||
rslt(bcx, base::trans_const_expr(ccx, l)));
|
rslt(bcx, trans_const_expr(ccx, l)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var(disr_val, _) { ret single_result(rslt(bcx, C_int(ccx, disr_val))); }
|
var(disr_val, _) { ret single_result(rslt(bcx, C_int(ccx, disr_val))); }
|
||||||
range(l1, l2) {
|
range(l1, l2) {
|
||||||
ret range_result(rslt(bcx, base::trans_const_expr(ccx, l1)),
|
ret range_result(rslt(bcx, trans_const_expr(ccx, l1)),
|
||||||
rslt(bcx, base::trans_const_expr(ccx, l2)));
|
rslt(bcx, trans_const_expr(ccx, l2)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -259,9 +258,9 @@ fn get_options(ccx: @crate_ctxt, m: match, col: uint) -> [opt] {
|
||||||
ret found;
|
ret found;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn extract_variant_args(bcx: @block_ctxt, pat_id: ast::node_id,
|
fn extract_variant_args(bcx: block, pat_id: ast::node_id,
|
||||||
vdefs: {enm: def_id, var: def_id}, val: ValueRef) ->
|
vdefs: {enm: def_id, var: def_id}, val: ValueRef) ->
|
||||||
{vals: [ValueRef], bcx: @block_ctxt} {
|
{vals: [ValueRef], bcx: block} {
|
||||||
let ccx = bcx.fcx.ccx, bcx = bcx;
|
let ccx = bcx.fcx.ccx, bcx = bcx;
|
||||||
// invariant:
|
// invariant:
|
||||||
// pat_id must have the same length ty_param_substs as vdefs?
|
// pat_id must have the same length ty_param_substs as vdefs?
|
||||||
|
@ -285,7 +284,7 @@ fn extract_variant_args(bcx: @block_ctxt, pat_id: ast::node_id,
|
||||||
// invariant needed:
|
// invariant needed:
|
||||||
// how do we know it even makes sense to pass in ty_param_substs
|
// how do we know it even makes sense to pass in ty_param_substs
|
||||||
// here? What if it's [] and the enum type has variables in it?
|
// here? What if it's [] and the enum type has variables in it?
|
||||||
base::GEP_enum(bcx, blobptr, vdefs_tg, vdefs_var,
|
GEP_enum(bcx, blobptr, vdefs_tg, vdefs_var,
|
||||||
ty_param_substs, i);
|
ty_param_substs, i);
|
||||||
bcx = r.bcx;
|
bcx = r.bcx;
|
||||||
args += [r.val];
|
args += [r.val];
|
||||||
|
@ -363,7 +362,7 @@ fn pick_col(m: match) -> uint {
|
||||||
ret best_col;
|
ret best_col;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn compile_submatch(bcx: @block_ctxt, m: match, vals: [ValueRef], f: mk_fail,
|
fn compile_submatch(bcx: block, m: match, vals: [ValueRef], f: mk_fail,
|
||||||
&exits: [exit_node]) {
|
&exits: [exit_node]) {
|
||||||
let bcx = bcx;
|
let bcx = bcx;
|
||||||
if m.len() == 0u { Br(bcx, f()); ret; }
|
if m.len() == 0u { Br(bcx, f()); ret; }
|
||||||
|
@ -371,23 +370,19 @@ fn compile_submatch(bcx: @block_ctxt, m: match, vals: [ValueRef], f: mk_fail,
|
||||||
let data = m[0].data;
|
let data = m[0].data;
|
||||||
alt data.guard {
|
alt data.guard {
|
||||||
some(e) {
|
some(e) {
|
||||||
let guard_cx = new_scope_block_ctxt(bcx, "submatch_guard");
|
// Temporarily set bindings. They'll be rewritten to PHI nodes
|
||||||
Br(bcx, guard_cx.llbb);
|
// for the actual arm block.
|
||||||
// Temporarily set bindings. They'll be rewritten to PHI nodes for
|
|
||||||
// the actual arm block.
|
|
||||||
data.id_map.items {|key, val|
|
data.id_map.items {|key, val|
|
||||||
let local = local_mem(option::get(assoc(key, m[0].bound)));
|
let loc = local_mem(option::get(assoc(key, m[0].bound)));
|
||||||
bcx.fcx.lllocals.insert(val, local);
|
bcx.fcx.lllocals.insert(val, loc);
|
||||||
|
};
|
||||||
|
let {bcx: guard_cx, val} = with_scope_result(bcx, "guard") {|bcx|
|
||||||
|
trans_temp_expr(bcx, e)
|
||||||
|
};
|
||||||
|
bcx = with_cond(guard_cx, Not(guard_cx, val)) {|bcx|
|
||||||
|
compile_submatch(bcx, vec::tail(m), vals, f, exits);
|
||||||
|
bcx
|
||||||
};
|
};
|
||||||
let {bcx: guard_bcx, val: guard_val} =
|
|
||||||
base::trans_temp_expr(guard_cx, e);
|
|
||||||
guard_bcx = base::trans_block_cleanups(guard_bcx, guard_cx);
|
|
||||||
let next_cx = new_sub_block_ctxt(guard_cx, "submatch_next");
|
|
||||||
let else_cx = new_sub_block_ctxt(guard_cx, "submatch_else");
|
|
||||||
CondBr(guard_bcx, guard_val, next_cx.llbb, else_cx.llbb);
|
|
||||||
compile_submatch(else_cx, vec::slice(m, 1u, m.len()), vals, f,
|
|
||||||
exits);
|
|
||||||
bcx = next_cx;
|
|
||||||
}
|
}
|
||||||
_ { }
|
_ { }
|
||||||
}
|
}
|
||||||
|
@ -425,7 +420,7 @@ fn compile_submatch(bcx: @block_ctxt, m: match, vals: [ValueRef], f: mk_fail,
|
||||||
let rec_vals = [];
|
let rec_vals = [];
|
||||||
for field_name: ast::ident in rec_fields {
|
for field_name: ast::ident in rec_fields {
|
||||||
let ix = option::get(ty::field_idx(field_name, fields));
|
let ix = option::get(ty::field_idx(field_name, fields));
|
||||||
let r = base::GEP_tup_like(bcx, rec_ty, val, [0, ix as int]);
|
let r = GEP_tup_like(bcx, rec_ty, val, [0, ix as int]);
|
||||||
rec_vals += [r.val];
|
rec_vals += [r.val];
|
||||||
bcx = r.bcx;
|
bcx = r.bcx;
|
||||||
}
|
}
|
||||||
|
@ -442,7 +437,7 @@ fn compile_submatch(bcx: @block_ctxt, m: match, vals: [ValueRef], f: mk_fail,
|
||||||
};
|
};
|
||||||
let tup_vals = [], i = 0u;
|
let tup_vals = [], i = 0u;
|
||||||
while i < n_tup_elts {
|
while i < n_tup_elts {
|
||||||
let r = base::GEP_tup_like(bcx, tup_ty, val, [0, i as int]);
|
let r = GEP_tup_like(bcx, tup_ty, val, [0, i as int]);
|
||||||
tup_vals += [r.val];
|
tup_vals += [r.val];
|
||||||
bcx = r.bcx;
|
bcx = r.bcx;
|
||||||
i += 1u;
|
i += 1u;
|
||||||
|
@ -507,7 +502,7 @@ fn compile_submatch(bcx: @block_ctxt, m: match, vals: [ValueRef], f: mk_fail,
|
||||||
let else_cx =
|
let else_cx =
|
||||||
alt kind {
|
alt kind {
|
||||||
no_branch | single { bcx }
|
no_branch | single { bcx }
|
||||||
_ { new_sub_block_ctxt(bcx, "match_else") }
|
_ { sub_block(bcx, "match_else") }
|
||||||
};
|
};
|
||||||
let sw;
|
let sw;
|
||||||
if kind == switch {
|
if kind == switch {
|
||||||
|
@ -521,7 +516,7 @@ fn compile_submatch(bcx: @block_ctxt, m: match, vals: [ValueRef], f: mk_fail,
|
||||||
|
|
||||||
// Compile subtrees for each option
|
// Compile subtrees for each option
|
||||||
for opt: opt in opts {
|
for opt: opt in opts {
|
||||||
let opt_cx = new_sub_block_ctxt(bcx, "match_case");
|
let opt_cx = sub_block(bcx, "match_case");
|
||||||
alt kind {
|
alt kind {
|
||||||
single { Br(bcx, opt_cx.llbb); }
|
single { Br(bcx, opt_cx.llbb); }
|
||||||
switch {
|
switch {
|
||||||
|
@ -536,35 +531,24 @@ fn compile_submatch(bcx: @block_ctxt, m: match, vals: [ValueRef], f: mk_fail,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
compare {
|
compare {
|
||||||
let compare_cx = new_scope_block_ctxt(bcx, "compare_scope");
|
|
||||||
Br(bcx, compare_cx.llbb);
|
|
||||||
bcx = compare_cx;
|
|
||||||
let t = node_id_type(bcx, pat_id);
|
let t = node_id_type(bcx, pat_id);
|
||||||
let res = trans_opt(bcx, opt);
|
let {bcx: after_cx, val: matches} =
|
||||||
alt res {
|
with_scope_result(bcx, "compare_scope") {|bcx|
|
||||||
single_result(r) {
|
alt trans_opt(bcx, opt) {
|
||||||
bcx = r.bcx;
|
single_result({bcx, val}) {
|
||||||
let eq =
|
trans_compare(bcx, ast::eq, test_val, t, val, t)
|
||||||
base::trans_compare(bcx, ast::eq, test_val, t, r.val, t);
|
}
|
||||||
let cleanup_cx = base::trans_block_cleanups(
|
range_result({val: vbegin, _}, {bcx, val: vend}) {
|
||||||
eq.bcx, compare_cx);
|
let {bcx, val: ge} = trans_compare(bcx, ast::ge, test_val,
|
||||||
bcx = new_sub_block_ctxt(bcx, "compare_next");
|
t, vbegin, t);
|
||||||
CondBr(cleanup_cx, eq.val, opt_cx.llbb, bcx.llbb);
|
let {bcx, val: le} = trans_compare(bcx, ast::le, test_val,
|
||||||
}
|
t, vend, t);
|
||||||
range_result(rbegin, rend) {
|
{bcx: bcx, val: And(bcx, ge, le)}
|
||||||
bcx = rend.bcx;
|
}
|
||||||
let ge = base::trans_compare(bcx, ast::ge, test_val, t,
|
}
|
||||||
rbegin.val, t);
|
};
|
||||||
let le = base::trans_compare(ge.bcx, ast::le, test_val, t,
|
bcx = sub_block(after_cx, "compare_next");
|
||||||
rend.val, t);
|
CondBr(after_cx, matches, opt_cx.llbb, bcx.llbb);
|
||||||
let in_range = rslt(le.bcx, And(le.bcx, ge.val, le.val));
|
|
||||||
bcx = in_range.bcx;
|
|
||||||
let cleanup_cx =
|
|
||||||
base::trans_block_cleanups(bcx, compare_cx);
|
|
||||||
bcx = new_sub_block_ctxt(bcx, "compare_next");
|
|
||||||
CondBr(cleanup_cx, in_range.val, opt_cx.llbb, bcx.llbb);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
_ { }
|
_ { }
|
||||||
}
|
}
|
||||||
|
@ -592,7 +576,7 @@ fn compile_submatch(bcx: @block_ctxt, m: match, vals: [ValueRef], f: mk_fail,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns false for unreachable blocks
|
// Returns false for unreachable blocks
|
||||||
fn make_phi_bindings(bcx: @block_ctxt, map: [exit_node],
|
fn make_phi_bindings(bcx: block, map: [exit_node],
|
||||||
ids: pat_util::pat_id_map) -> bool {
|
ids: pat_util::pat_id_map) -> bool {
|
||||||
let our_block = bcx.llbb as uint;
|
let our_block = bcx.llbb as uint;
|
||||||
let success = true, bcx = bcx;
|
let success = true, bcx = bcx;
|
||||||
|
@ -623,8 +607,8 @@ fn make_phi_bindings(bcx: @block_ctxt, map: [exit_node],
|
||||||
make_phi_bindings"); }
|
make_phi_bindings"); }
|
||||||
};
|
};
|
||||||
let e_ty = node_id_type(bcx, node_id);
|
let e_ty = node_id_type(bcx, node_id);
|
||||||
let {bcx: abcx, val: alloc} = base::alloc_ty(bcx, e_ty);
|
let {bcx: abcx, val: alloc} = alloc_ty(bcx, e_ty);
|
||||||
bcx = base::copy_val(abcx, base::INIT, alloc,
|
bcx = copy_val(abcx, INIT, alloc,
|
||||||
load_if_immediate(abcx, local, e_ty),
|
load_if_immediate(abcx, local, e_ty),
|
||||||
e_ty);
|
e_ty);
|
||||||
add_clean(bcx, alloc, e_ty);
|
add_clean(bcx, alloc, e_ty);
|
||||||
|
@ -637,76 +621,72 @@ fn make_phi_bindings(bcx: @block_ctxt, map: [exit_node],
|
||||||
ret success;
|
ret success;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn trans_alt(cx: @block_ctxt, expr: @ast::expr, arms_: [ast::arm],
|
fn trans_alt(bcx: block, expr: @ast::expr, arms: [ast::arm],
|
||||||
dest: base::dest) -> @block_ctxt {
|
dest: dest) -> block {
|
||||||
let bodies = [];
|
with_scope(bcx, "alt") {|bcx| trans_alt_inner(bcx, expr, arms, dest)}
|
||||||
let match: match = [];
|
}
|
||||||
let alt_cx = new_scope_block_ctxt(cx, "alt");
|
|
||||||
Br(cx, alt_cx.llbb);
|
|
||||||
|
|
||||||
let er = base::trans_temp_expr(alt_cx, expr);
|
fn trans_alt_inner(scope_cx: block, expr: @ast::expr, arms: [ast::arm],
|
||||||
if er.bcx.unreachable { ret er.bcx; }
|
dest: dest) -> block {
|
||||||
|
let bcx = scope_cx, tcx = bcx_tcx(bcx);
|
||||||
|
let bodies = [], match = [];
|
||||||
|
|
||||||
/*
|
let {bcx, val, _} = trans_temp_expr(bcx, expr);
|
||||||
n.b. nothing else in this module should need to normalize,
|
if bcx.unreachable { ret bcx; }
|
||||||
b/c of this call
|
|
||||||
*/
|
|
||||||
let arms = normalize_arms(bcx_tcx(cx), arms_);
|
|
||||||
|
|
||||||
for a: ast::arm in arms {
|
// n.b. nothing else in this module should need to normalize,
|
||||||
let body = new_real_block_ctxt(er.bcx, "case_body",
|
// b/c of this call
|
||||||
a.body.span);
|
let arms = normalize_arms(tcx, arms);
|
||||||
let id_map = pat_util::pat_id_map(bcx_tcx(cx), a.pats[0]);
|
|
||||||
|
for a in arms {
|
||||||
|
let body = scope_block(bcx, "case_body");
|
||||||
|
body.block_span = some(a.body.span);
|
||||||
|
let id_map = pat_util::pat_id_map(tcx, a.pats[0]);
|
||||||
bodies += [body];
|
bodies += [body];
|
||||||
for p: @ast::pat in a.pats {
|
for p in a.pats {
|
||||||
match +=
|
match += [@{pats: [p],
|
||||||
[@{pats: [p],
|
bound: [],
|
||||||
bound: [],
|
data: @{body: body.llbb, guard: a.guard,
|
||||||
data: @{body: body.llbb, guard: a.guard, id_map: id_map}}];
|
id_map: id_map}}];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Cached fail-on-fallthrough block
|
// Cached fail-on-fallthrough block
|
||||||
let fail_cx = @mutable none;
|
let fail_cx = @mutable none;
|
||||||
fn mk_fail(cx: @block_ctxt, sp: span,
|
fn mk_fail(bcx: block, sp: span,
|
||||||
done: @mutable option<BasicBlockRef>) -> BasicBlockRef {
|
done: @mutable option<BasicBlockRef>) -> BasicBlockRef {
|
||||||
alt *done { some(bb) { ret bb; } _ { } }
|
alt *done { some(bb) { ret bb; } _ { } }
|
||||||
let fail_cx = new_sub_block_ctxt(cx, "case_fallthrough");
|
let fail_cx = sub_block(bcx, "case_fallthrough");
|
||||||
base::trans_fail(fail_cx, some(sp), "non-exhaustive match failure");;
|
trans_fail(fail_cx, some(sp), "non-exhaustive match failure");;
|
||||||
*done = some(fail_cx.llbb);
|
*done = some(fail_cx.llbb);
|
||||||
ret fail_cx.llbb;
|
ret fail_cx.llbb;
|
||||||
}
|
}
|
||||||
|
|
||||||
let exit_map = [];
|
let exit_map = [];
|
||||||
let t = node_id_type(cx, expr.id);
|
let t = node_id_type(bcx, expr.id);
|
||||||
let vr = base::spill_if_immediate(er.bcx, er.val, t);
|
let {bcx, val: spilled} = spill_if_immediate(bcx, val, t);
|
||||||
compile_submatch(vr.bcx, match, [vr.val],
|
compile_submatch(bcx, match, [spilled],
|
||||||
bind mk_fail(alt_cx, expr.span, fail_cx), exit_map);
|
bind mk_fail(scope_cx, expr.span, fail_cx), exit_map);
|
||||||
|
|
||||||
let arm_cxs = [], arm_dests = [], i = 0u;
|
let arm_cxs = [], arm_dests = [], i = 0u;
|
||||||
for a: ast::arm in arms {
|
for a in arms {
|
||||||
let body_cx = bodies[i];
|
let body_cx = bodies[i];
|
||||||
if make_phi_bindings(body_cx, exit_map,
|
if make_phi_bindings(body_cx, exit_map,
|
||||||
pat_util::pat_id_map(bcx_tcx(cx),
|
pat_util::pat_id_map(tcx, a.pats[0])) {
|
||||||
a.pats[0])) {
|
let arm_dest = dup_for_join(dest);
|
||||||
let arm_dest = base::dup_for_join(dest);
|
|
||||||
arm_dests += [arm_dest];
|
arm_dests += [arm_dest];
|
||||||
let arm_cx = base::trans_block(body_cx, a.body, arm_dest);
|
let arm_cx = trans_block(body_cx, a.body, arm_dest);
|
||||||
arm_cx = base::trans_block_cleanups(arm_cx, body_cx);
|
arm_cx = trans_block_cleanups(arm_cx, body_cx);
|
||||||
arm_cxs += [arm_cx];
|
arm_cxs += [arm_cx];
|
||||||
}
|
}
|
||||||
i += 1u;
|
i += 1u;
|
||||||
}
|
}
|
||||||
let after_cx = base::join_returns(alt_cx, arm_cxs, arm_dests, dest);
|
join_returns(scope_cx, arm_cxs, arm_dests, dest)
|
||||||
let next_cx = new_sub_block_ctxt(cx, "next");
|
|
||||||
if after_cx.unreachable { Unreachable(next_cx); }
|
|
||||||
base::cleanup_and_Br(after_cx, alt_cx, next_cx.llbb);
|
|
||||||
ret next_cx;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Not alt-related, but similar to the pattern-munging code above
|
// Not alt-related, but similar to the pattern-munging code above
|
||||||
fn bind_irrefutable_pat(bcx: @block_ctxt, pat: @ast::pat, val: ValueRef,
|
fn bind_irrefutable_pat(bcx: block, pat: @ast::pat, val: ValueRef,
|
||||||
make_copy: bool) -> @block_ctxt {
|
make_copy: bool) -> block {
|
||||||
let ccx = bcx.fcx.ccx, bcx = bcx;
|
let ccx = bcx.fcx.ccx, bcx = bcx;
|
||||||
|
|
||||||
// Necessary since bind_irrefutable_pat is called outside trans_alt
|
// Necessary since bind_irrefutable_pat is called outside trans_alt
|
||||||
|
@ -717,10 +697,10 @@ fn bind_irrefutable_pat(bcx: @block_ctxt, pat: @ast::pat, val: ValueRef,
|
||||||
// FIXME: Could constrain pat_bind to make this
|
// FIXME: Could constrain pat_bind to make this
|
||||||
// check unnecessary.
|
// check unnecessary.
|
||||||
check (type_has_static_size(ccx, ty));
|
check (type_has_static_size(ccx, ty));
|
||||||
let llty = base::type_of(ccx, ty);
|
let llty = type_of(ccx, ty);
|
||||||
let alloc = base::alloca(bcx, llty);
|
let alloc = alloca(bcx, llty);
|
||||||
bcx = base::copy_val(bcx, base::INIT, alloc,
|
bcx = copy_val(bcx, INIT, alloc,
|
||||||
base::load_if_immediate(bcx, val, ty), ty);
|
load_if_immediate(bcx, val, ty), ty);
|
||||||
bcx.fcx.lllocals.insert(pat.id, local_mem(alloc));
|
bcx.fcx.lllocals.insert(pat.id, local_mem(alloc));
|
||||||
add_clean(bcx, alloc, ty);
|
add_clean(bcx, alloc, ty);
|
||||||
} else { bcx.fcx.lllocals.insert(pat.id, local_mem(val)); }
|
} else { bcx.fcx.lllocals.insert(pat.id, local_mem(val)); }
|
||||||
|
@ -745,7 +725,7 @@ fn bind_irrefutable_pat(bcx: @block_ctxt, pat: @ast::pat, val: ValueRef,
|
||||||
for f: ast::field_pat in fields {
|
for f: ast::field_pat in fields {
|
||||||
let ix = option::get(ty::field_idx(f.ident, rec_fields));
|
let ix = option::get(ty::field_idx(f.ident, rec_fields));
|
||||||
// how to get rid of this check?
|
// how to get rid of this check?
|
||||||
let r = base::GEP_tup_like(bcx, rec_ty, val, [0, ix as int]);
|
let r = GEP_tup_like(bcx, rec_ty, val, [0, ix as int]);
|
||||||
bcx = bind_irrefutable_pat(r.bcx, f.pat, r.val, make_copy);
|
bcx = bind_irrefutable_pat(r.bcx, f.pat, r.val, make_copy);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -753,7 +733,7 @@ fn bind_irrefutable_pat(bcx: @block_ctxt, pat: @ast::pat, val: ValueRef,
|
||||||
let tup_ty = node_id_type(bcx, pat.id);
|
let tup_ty = node_id_type(bcx, pat.id);
|
||||||
let i = 0u;
|
let i = 0u;
|
||||||
for elem in elems {
|
for elem in elems {
|
||||||
let r = base::GEP_tup_like(bcx, tup_ty, val, [0, i as int]);
|
let r = GEP_tup_like(bcx, tup_ty, val, [0, i as int]);
|
||||||
bcx = bind_irrefutable_pat(r.bcx, elem, r.val, make_copy);
|
bcx = bind_irrefutable_pat(r.bcx, elem, r.val, make_copy);
|
||||||
i += 1u;
|
i += 1u;
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -6,10 +6,10 @@ import codemap::span;
|
||||||
import lib::llvm::{ValueRef, TypeRef, BasicBlockRef, BuilderRef, ModuleRef};
|
import lib::llvm::{ValueRef, TypeRef, BasicBlockRef, BuilderRef, ModuleRef};
|
||||||
import lib::llvm::{Opcode, IntPredicate, RealPredicate, True, False,
|
import lib::llvm::{Opcode, IntPredicate, RealPredicate, True, False,
|
||||||
CallConv};
|
CallConv};
|
||||||
import common::{block_ctxt, T_ptr, T_nil, T_i8, T_i1, T_void,
|
import common::{block, T_ptr, T_nil, T_i8, T_i1, T_void,
|
||||||
T_fn, val_ty, bcx_ccx, C_i32, val_str};
|
T_fn, val_ty, bcx_ccx, C_i32, val_str};
|
||||||
|
|
||||||
fn B(cx: @block_ctxt) -> BuilderRef {
|
fn B(cx: block) -> BuilderRef {
|
||||||
let b = *cx.fcx.ccx.builder;
|
let b = *cx.fcx.ccx.builder;
|
||||||
llvm::LLVMPositionBuilderAtEnd(b, cx.llbb);
|
llvm::LLVMPositionBuilderAtEnd(b, cx.llbb);
|
||||||
ret b;
|
ret b;
|
||||||
|
@ -23,21 +23,21 @@ fn B(cx: @block_ctxt) -> BuilderRef {
|
||||||
// for (fail/break/ret statements, call to diverging functions, etc), and
|
// for (fail/break/ret statements, call to diverging functions, etc), and
|
||||||
// further instructions to the block should simply be ignored.
|
// further instructions to the block should simply be ignored.
|
||||||
|
|
||||||
fn RetVoid(cx: @block_ctxt) {
|
fn RetVoid(cx: block) {
|
||||||
if cx.unreachable { ret; }
|
if cx.unreachable { ret; }
|
||||||
assert (!cx.terminated);
|
assert (!cx.terminated);
|
||||||
cx.terminated = true;
|
cx.terminated = true;
|
||||||
llvm::LLVMBuildRetVoid(B(cx));
|
llvm::LLVMBuildRetVoid(B(cx));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn Ret(cx: @block_ctxt, V: ValueRef) {
|
fn Ret(cx: block, V: ValueRef) {
|
||||||
if cx.unreachable { ret; }
|
if cx.unreachable { ret; }
|
||||||
assert (!cx.terminated);
|
assert (!cx.terminated);
|
||||||
cx.terminated = true;
|
cx.terminated = true;
|
||||||
llvm::LLVMBuildRet(B(cx), V);
|
llvm::LLVMBuildRet(B(cx), V);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn AggregateRet(cx: @block_ctxt, RetVals: [ValueRef]) {
|
fn AggregateRet(cx: block, RetVals: [ValueRef]) {
|
||||||
if cx.unreachable { ret; }
|
if cx.unreachable { ret; }
|
||||||
assert (!cx.terminated);
|
assert (!cx.terminated);
|
||||||
cx.terminated = true;
|
cx.terminated = true;
|
||||||
|
@ -47,14 +47,14 @@ fn AggregateRet(cx: @block_ctxt, RetVals: [ValueRef]) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn Br(cx: @block_ctxt, Dest: BasicBlockRef) {
|
fn Br(cx: block, Dest: BasicBlockRef) {
|
||||||
if cx.unreachable { ret; }
|
if cx.unreachable { ret; }
|
||||||
assert (!cx.terminated);
|
assert (!cx.terminated);
|
||||||
cx.terminated = true;
|
cx.terminated = true;
|
||||||
llvm::LLVMBuildBr(B(cx), Dest);
|
llvm::LLVMBuildBr(B(cx), Dest);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn CondBr(cx: @block_ctxt, If: ValueRef, Then: BasicBlockRef,
|
fn CondBr(cx: block, If: ValueRef, Then: BasicBlockRef,
|
||||||
Else: BasicBlockRef) {
|
Else: BasicBlockRef) {
|
||||||
if cx.unreachable { ret; }
|
if cx.unreachable { ret; }
|
||||||
assert (!cx.terminated);
|
assert (!cx.terminated);
|
||||||
|
@ -62,7 +62,7 @@ fn CondBr(cx: @block_ctxt, If: ValueRef, Then: BasicBlockRef,
|
||||||
llvm::LLVMBuildCondBr(B(cx), If, Then, Else);
|
llvm::LLVMBuildCondBr(B(cx), If, Then, Else);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn Switch(cx: @block_ctxt, V: ValueRef, Else: BasicBlockRef, NumCases: uint)
|
fn Switch(cx: block, V: ValueRef, Else: BasicBlockRef, NumCases: uint)
|
||||||
-> ValueRef {
|
-> ValueRef {
|
||||||
if cx.unreachable { ret _Undef(V); }
|
if cx.unreachable { ret _Undef(V); }
|
||||||
assert !cx.terminated;
|
assert !cx.terminated;
|
||||||
|
@ -75,7 +75,7 @@ fn AddCase(S: ValueRef, OnVal: ValueRef, Dest: BasicBlockRef) {
|
||||||
llvm::LLVMAddCase(S, OnVal, Dest);
|
llvm::LLVMAddCase(S, OnVal, Dest);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn IndirectBr(cx: @block_ctxt, Addr: ValueRef, NumDests: uint) {
|
fn IndirectBr(cx: block, Addr: ValueRef, NumDests: uint) {
|
||||||
if cx.unreachable { ret; }
|
if cx.unreachable { ret; }
|
||||||
assert (!cx.terminated);
|
assert (!cx.terminated);
|
||||||
cx.terminated = true;
|
cx.terminated = true;
|
||||||
|
@ -89,7 +89,7 @@ fn noname() -> sbuf unsafe {
|
||||||
ret unsafe::reinterpret_cast(ptr::addr_of(cnull));
|
ret unsafe::reinterpret_cast(ptr::addr_of(cnull));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn Invoke(cx: @block_ctxt, Fn: ValueRef, Args: [ValueRef],
|
fn Invoke(cx: block, Fn: ValueRef, Args: [ValueRef],
|
||||||
Then: BasicBlockRef, Catch: BasicBlockRef) {
|
Then: BasicBlockRef, Catch: BasicBlockRef) {
|
||||||
if cx.unreachable { ret; }
|
if cx.unreachable { ret; }
|
||||||
assert (!cx.terminated);
|
assert (!cx.terminated);
|
||||||
|
@ -105,7 +105,7 @@ fn Invoke(cx: @block_ctxt, Fn: ValueRef, Args: [ValueRef],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn FastInvoke(cx: @block_ctxt, Fn: ValueRef, Args: [ValueRef],
|
fn FastInvoke(cx: block, Fn: ValueRef, Args: [ValueRef],
|
||||||
Then: BasicBlockRef, Catch: BasicBlockRef) {
|
Then: BasicBlockRef, Catch: BasicBlockRef) {
|
||||||
if cx.unreachable { ret; }
|
if cx.unreachable { ret; }
|
||||||
assert (!cx.terminated);
|
assert (!cx.terminated);
|
||||||
|
@ -118,7 +118,7 @@ fn FastInvoke(cx: @block_ctxt, Fn: ValueRef, Args: [ValueRef],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn Unreachable(cx: @block_ctxt) {
|
fn Unreachable(cx: block) {
|
||||||
if cx.unreachable { ret; }
|
if cx.unreachable { ret; }
|
||||||
cx.unreachable = true;
|
cx.unreachable = true;
|
||||||
if !cx.terminated { llvm::LLVMBuildUnreachable(B(cx)); }
|
if !cx.terminated { llvm::LLVMBuildUnreachable(B(cx)); }
|
||||||
|
@ -129,188 +129,188 @@ fn _Undef(val: ValueRef) -> ValueRef {
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Arithmetic */
|
/* Arithmetic */
|
||||||
fn Add(cx: @block_ctxt, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
|
fn Add(cx: block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
|
||||||
if cx.unreachable { ret _Undef(LHS); }
|
if cx.unreachable { ret _Undef(LHS); }
|
||||||
ret llvm::LLVMBuildAdd(B(cx), LHS, RHS, noname());
|
ret llvm::LLVMBuildAdd(B(cx), LHS, RHS, noname());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn NSWAdd(cx: @block_ctxt, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
|
fn NSWAdd(cx: block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
|
||||||
if cx.unreachable { ret _Undef(LHS); }
|
if cx.unreachable { ret _Undef(LHS); }
|
||||||
ret llvm::LLVMBuildNSWAdd(B(cx), LHS, RHS, noname());
|
ret llvm::LLVMBuildNSWAdd(B(cx), LHS, RHS, noname());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn NUWAdd(cx: @block_ctxt, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
|
fn NUWAdd(cx: block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
|
||||||
if cx.unreachable { ret _Undef(LHS); }
|
if cx.unreachable { ret _Undef(LHS); }
|
||||||
ret llvm::LLVMBuildNUWAdd(B(cx), LHS, RHS, noname());
|
ret llvm::LLVMBuildNUWAdd(B(cx), LHS, RHS, noname());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn FAdd(cx: @block_ctxt, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
|
fn FAdd(cx: block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
|
||||||
if cx.unreachable { ret _Undef(LHS); }
|
if cx.unreachable { ret _Undef(LHS); }
|
||||||
ret llvm::LLVMBuildFAdd(B(cx), LHS, RHS, noname());
|
ret llvm::LLVMBuildFAdd(B(cx), LHS, RHS, noname());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn Sub(cx: @block_ctxt, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
|
fn Sub(cx: block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
|
||||||
if cx.unreachable { ret _Undef(LHS); }
|
if cx.unreachable { ret _Undef(LHS); }
|
||||||
ret llvm::LLVMBuildSub(B(cx), LHS, RHS, noname());
|
ret llvm::LLVMBuildSub(B(cx), LHS, RHS, noname());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn NSWSub(cx: @block_ctxt, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
|
fn NSWSub(cx: block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
|
||||||
if cx.unreachable { ret _Undef(LHS); }
|
if cx.unreachable { ret _Undef(LHS); }
|
||||||
ret llvm::LLVMBuildNSWSub(B(cx), LHS, RHS, noname());
|
ret llvm::LLVMBuildNSWSub(B(cx), LHS, RHS, noname());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn NUWSub(cx: @block_ctxt, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
|
fn NUWSub(cx: block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
|
||||||
if cx.unreachable { ret _Undef(LHS); }
|
if cx.unreachable { ret _Undef(LHS); }
|
||||||
ret llvm::LLVMBuildNUWSub(B(cx), LHS, RHS, noname());
|
ret llvm::LLVMBuildNUWSub(B(cx), LHS, RHS, noname());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn FSub(cx: @block_ctxt, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
|
fn FSub(cx: block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
|
||||||
if cx.unreachable { ret _Undef(LHS); }
|
if cx.unreachable { ret _Undef(LHS); }
|
||||||
ret llvm::LLVMBuildFSub(B(cx), LHS, RHS, noname());
|
ret llvm::LLVMBuildFSub(B(cx), LHS, RHS, noname());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn Mul(cx: @block_ctxt, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
|
fn Mul(cx: block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
|
||||||
if cx.unreachable { ret _Undef(LHS); }
|
if cx.unreachable { ret _Undef(LHS); }
|
||||||
ret llvm::LLVMBuildMul(B(cx), LHS, RHS, noname());
|
ret llvm::LLVMBuildMul(B(cx), LHS, RHS, noname());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn NSWMul(cx: @block_ctxt, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
|
fn NSWMul(cx: block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
|
||||||
if cx.unreachable { ret _Undef(LHS); }
|
if cx.unreachable { ret _Undef(LHS); }
|
||||||
ret llvm::LLVMBuildNSWMul(B(cx), LHS, RHS, noname());
|
ret llvm::LLVMBuildNSWMul(B(cx), LHS, RHS, noname());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn NUWMul(cx: @block_ctxt, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
|
fn NUWMul(cx: block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
|
||||||
if cx.unreachable { ret _Undef(LHS); }
|
if cx.unreachable { ret _Undef(LHS); }
|
||||||
ret llvm::LLVMBuildNUWMul(B(cx), LHS, RHS, noname());
|
ret llvm::LLVMBuildNUWMul(B(cx), LHS, RHS, noname());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn FMul(cx: @block_ctxt, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
|
fn FMul(cx: block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
|
||||||
if cx.unreachable { ret _Undef(LHS); }
|
if cx.unreachable { ret _Undef(LHS); }
|
||||||
ret llvm::LLVMBuildFMul(B(cx), LHS, RHS, noname());
|
ret llvm::LLVMBuildFMul(B(cx), LHS, RHS, noname());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn UDiv(cx: @block_ctxt, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
|
fn UDiv(cx: block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
|
||||||
if cx.unreachable { ret _Undef(LHS); }
|
if cx.unreachable { ret _Undef(LHS); }
|
||||||
ret llvm::LLVMBuildUDiv(B(cx), LHS, RHS, noname());
|
ret llvm::LLVMBuildUDiv(B(cx), LHS, RHS, noname());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn SDiv(cx: @block_ctxt, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
|
fn SDiv(cx: block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
|
||||||
if cx.unreachable { ret _Undef(LHS); }
|
if cx.unreachable { ret _Undef(LHS); }
|
||||||
ret llvm::LLVMBuildSDiv(B(cx), LHS, RHS, noname());
|
ret llvm::LLVMBuildSDiv(B(cx), LHS, RHS, noname());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn ExactSDiv(cx: @block_ctxt, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
|
fn ExactSDiv(cx: block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
|
||||||
if cx.unreachable { ret _Undef(LHS); }
|
if cx.unreachable { ret _Undef(LHS); }
|
||||||
ret llvm::LLVMBuildExactSDiv(B(cx), LHS, RHS, noname());
|
ret llvm::LLVMBuildExactSDiv(B(cx), LHS, RHS, noname());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn FDiv(cx: @block_ctxt, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
|
fn FDiv(cx: block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
|
||||||
if cx.unreachable { ret _Undef(LHS); }
|
if cx.unreachable { ret _Undef(LHS); }
|
||||||
ret llvm::LLVMBuildFDiv(B(cx), LHS, RHS, noname());
|
ret llvm::LLVMBuildFDiv(B(cx), LHS, RHS, noname());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn URem(cx: @block_ctxt, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
|
fn URem(cx: block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
|
||||||
if cx.unreachable { ret _Undef(LHS); }
|
if cx.unreachable { ret _Undef(LHS); }
|
||||||
ret llvm::LLVMBuildURem(B(cx), LHS, RHS, noname());
|
ret llvm::LLVMBuildURem(B(cx), LHS, RHS, noname());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn SRem(cx: @block_ctxt, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
|
fn SRem(cx: block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
|
||||||
if cx.unreachable { ret _Undef(LHS); }
|
if cx.unreachable { ret _Undef(LHS); }
|
||||||
ret llvm::LLVMBuildSRem(B(cx), LHS, RHS, noname());
|
ret llvm::LLVMBuildSRem(B(cx), LHS, RHS, noname());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn FRem(cx: @block_ctxt, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
|
fn FRem(cx: block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
|
||||||
if cx.unreachable { ret _Undef(LHS); }
|
if cx.unreachable { ret _Undef(LHS); }
|
||||||
ret llvm::LLVMBuildFRem(B(cx), LHS, RHS, noname());
|
ret llvm::LLVMBuildFRem(B(cx), LHS, RHS, noname());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn Shl(cx: @block_ctxt, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
|
fn Shl(cx: block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
|
||||||
if cx.unreachable { ret _Undef(LHS); }
|
if cx.unreachable { ret _Undef(LHS); }
|
||||||
ret llvm::LLVMBuildShl(B(cx), LHS, RHS, noname());
|
ret llvm::LLVMBuildShl(B(cx), LHS, RHS, noname());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn LShr(cx: @block_ctxt, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
|
fn LShr(cx: block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
|
||||||
if cx.unreachable { ret _Undef(LHS); }
|
if cx.unreachable { ret _Undef(LHS); }
|
||||||
ret llvm::LLVMBuildLShr(B(cx), LHS, RHS, noname());
|
ret llvm::LLVMBuildLShr(B(cx), LHS, RHS, noname());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn AShr(cx: @block_ctxt, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
|
fn AShr(cx: block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
|
||||||
if cx.unreachable { ret _Undef(LHS); }
|
if cx.unreachable { ret _Undef(LHS); }
|
||||||
ret llvm::LLVMBuildAShr(B(cx), LHS, RHS, noname());
|
ret llvm::LLVMBuildAShr(B(cx), LHS, RHS, noname());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn And(cx: @block_ctxt, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
|
fn And(cx: block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
|
||||||
if cx.unreachable { ret _Undef(LHS); }
|
if cx.unreachable { ret _Undef(LHS); }
|
||||||
ret llvm::LLVMBuildAnd(B(cx), LHS, RHS, noname());
|
ret llvm::LLVMBuildAnd(B(cx), LHS, RHS, noname());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn Or(cx: @block_ctxt, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
|
fn Or(cx: block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
|
||||||
if cx.unreachable { ret _Undef(LHS); }
|
if cx.unreachable { ret _Undef(LHS); }
|
||||||
ret llvm::LLVMBuildOr(B(cx), LHS, RHS, noname());
|
ret llvm::LLVMBuildOr(B(cx), LHS, RHS, noname());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn Xor(cx: @block_ctxt, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
|
fn Xor(cx: block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
|
||||||
if cx.unreachable { ret _Undef(LHS); }
|
if cx.unreachable { ret _Undef(LHS); }
|
||||||
ret llvm::LLVMBuildXor(B(cx), LHS, RHS, noname());
|
ret llvm::LLVMBuildXor(B(cx), LHS, RHS, noname());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn BinOp(cx: @block_ctxt, Op: Opcode, LHS: ValueRef, RHS: ValueRef) ->
|
fn BinOp(cx: block, Op: Opcode, LHS: ValueRef, RHS: ValueRef) ->
|
||||||
ValueRef {
|
ValueRef {
|
||||||
if cx.unreachable { ret _Undef(LHS); }
|
if cx.unreachable { ret _Undef(LHS); }
|
||||||
ret llvm::LLVMBuildBinOp(B(cx), Op, LHS, RHS, noname());
|
ret llvm::LLVMBuildBinOp(B(cx), Op, LHS, RHS, noname());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn Neg(cx: @block_ctxt, V: ValueRef) -> ValueRef {
|
fn Neg(cx: block, V: ValueRef) -> ValueRef {
|
||||||
if cx.unreachable { ret _Undef(V); }
|
if cx.unreachable { ret _Undef(V); }
|
||||||
ret llvm::LLVMBuildNeg(B(cx), V, noname());
|
ret llvm::LLVMBuildNeg(B(cx), V, noname());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn NSWNeg(cx: @block_ctxt, V: ValueRef) -> ValueRef {
|
fn NSWNeg(cx: block, V: ValueRef) -> ValueRef {
|
||||||
if cx.unreachable { ret _Undef(V); }
|
if cx.unreachable { ret _Undef(V); }
|
||||||
ret llvm::LLVMBuildNSWNeg(B(cx), V, noname());
|
ret llvm::LLVMBuildNSWNeg(B(cx), V, noname());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn NUWNeg(cx: @block_ctxt, V: ValueRef) -> ValueRef {
|
fn NUWNeg(cx: block, V: ValueRef) -> ValueRef {
|
||||||
if cx.unreachable { ret _Undef(V); }
|
if cx.unreachable { ret _Undef(V); }
|
||||||
ret llvm::LLVMBuildNUWNeg(B(cx), V, noname());
|
ret llvm::LLVMBuildNUWNeg(B(cx), V, noname());
|
||||||
}
|
}
|
||||||
fn FNeg(cx: @block_ctxt, V: ValueRef) -> ValueRef {
|
fn FNeg(cx: block, V: ValueRef) -> ValueRef {
|
||||||
if cx.unreachable { ret _Undef(V); }
|
if cx.unreachable { ret _Undef(V); }
|
||||||
ret llvm::LLVMBuildFNeg(B(cx), V, noname());
|
ret llvm::LLVMBuildFNeg(B(cx), V, noname());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn Not(cx: @block_ctxt, V: ValueRef) -> ValueRef {
|
fn Not(cx: block, V: ValueRef) -> ValueRef {
|
||||||
if cx.unreachable { ret _Undef(V); }
|
if cx.unreachable { ret _Undef(V); }
|
||||||
ret llvm::LLVMBuildNot(B(cx), V, noname());
|
ret llvm::LLVMBuildNot(B(cx), V, noname());
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Memory */
|
/* Memory */
|
||||||
fn Malloc(cx: @block_ctxt, Ty: TypeRef) -> ValueRef {
|
fn Malloc(cx: block, Ty: TypeRef) -> ValueRef {
|
||||||
if cx.unreachable { ret llvm::LLVMGetUndef(T_ptr(T_i8())); }
|
if cx.unreachable { ret llvm::LLVMGetUndef(T_ptr(T_i8())); }
|
||||||
ret llvm::LLVMBuildMalloc(B(cx), Ty, noname());
|
ret llvm::LLVMBuildMalloc(B(cx), Ty, noname());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn ArrayMalloc(cx: @block_ctxt, Ty: TypeRef, Val: ValueRef) -> ValueRef {
|
fn ArrayMalloc(cx: block, Ty: TypeRef, Val: ValueRef) -> ValueRef {
|
||||||
if cx.unreachable { ret llvm::LLVMGetUndef(T_ptr(T_i8())); }
|
if cx.unreachable { ret llvm::LLVMGetUndef(T_ptr(T_i8())); }
|
||||||
ret llvm::LLVMBuildArrayMalloc(B(cx), Ty, Val, noname());
|
ret llvm::LLVMBuildArrayMalloc(B(cx), Ty, Val, noname());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn Alloca(cx: @block_ctxt, Ty: TypeRef) -> ValueRef {
|
fn Alloca(cx: block, Ty: TypeRef) -> ValueRef {
|
||||||
if cx.unreachable { ret llvm::LLVMGetUndef(T_ptr(Ty)); }
|
if cx.unreachable { ret llvm::LLVMGetUndef(T_ptr(Ty)); }
|
||||||
ret llvm::LLVMBuildAlloca(B(cx), Ty, noname());
|
ret llvm::LLVMBuildAlloca(B(cx), Ty, noname());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn ArrayAlloca(cx: @block_ctxt, Ty: TypeRef, Val: ValueRef) -> ValueRef {
|
fn ArrayAlloca(cx: block, Ty: TypeRef, Val: ValueRef) -> ValueRef {
|
||||||
if cx.unreachable { ret llvm::LLVMGetUndef(T_ptr(Ty)); }
|
if cx.unreachable { ret llvm::LLVMGetUndef(T_ptr(Ty)); }
|
||||||
ret llvm::LLVMBuildArrayAlloca(B(cx), Ty, Val, noname());
|
ret llvm::LLVMBuildArrayAlloca(B(cx), Ty, Val, noname());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn Free(cx: @block_ctxt, PointerVal: ValueRef) {
|
fn Free(cx: block, PointerVal: ValueRef) {
|
||||||
if cx.unreachable { ret; }
|
if cx.unreachable { ret; }
|
||||||
llvm::LLVMBuildFree(B(cx), PointerVal);
|
llvm::LLVMBuildFree(B(cx), PointerVal);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn Load(cx: @block_ctxt, PointerVal: ValueRef) -> ValueRef {
|
fn Load(cx: block, PointerVal: ValueRef) -> ValueRef {
|
||||||
let ccx = cx.fcx.ccx;
|
let ccx = cx.fcx.ccx;
|
||||||
if cx.unreachable {
|
if cx.unreachable {
|
||||||
let ty = val_ty(PointerVal);
|
let ty = val_ty(PointerVal);
|
||||||
|
@ -321,12 +321,12 @@ fn Load(cx: @block_ctxt, PointerVal: ValueRef) -> ValueRef {
|
||||||
ret llvm::LLVMBuildLoad(B(cx), PointerVal, noname());
|
ret llvm::LLVMBuildLoad(B(cx), PointerVal, noname());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn Store(cx: @block_ctxt, Val: ValueRef, Ptr: ValueRef) {
|
fn Store(cx: block, Val: ValueRef, Ptr: ValueRef) {
|
||||||
if cx.unreachable { ret; }
|
if cx.unreachable { ret; }
|
||||||
llvm::LLVMBuildStore(B(cx), Val, Ptr);
|
llvm::LLVMBuildStore(B(cx), Val, Ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn GEP(cx: @block_ctxt, Pointer: ValueRef, Indices: [ValueRef]) -> ValueRef {
|
fn GEP(cx: block, Pointer: ValueRef, Indices: [ValueRef]) -> ValueRef {
|
||||||
if cx.unreachable { ret llvm::LLVMGetUndef(T_ptr(T_nil())); }
|
if cx.unreachable { ret llvm::LLVMGetUndef(T_ptr(T_nil())); }
|
||||||
unsafe {
|
unsafe {
|
||||||
ret llvm::LLVMBuildGEP(B(cx), Pointer, vec::to_ptr(Indices),
|
ret llvm::LLVMBuildGEP(B(cx), Pointer, vec::to_ptr(Indices),
|
||||||
|
@ -336,13 +336,13 @@ fn GEP(cx: @block_ctxt, Pointer: ValueRef, Indices: [ValueRef]) -> ValueRef {
|
||||||
|
|
||||||
// Simple wrapper around GEP that takes an array of ints and wraps them
|
// Simple wrapper around GEP that takes an array of ints and wraps them
|
||||||
// in C_i32()
|
// in C_i32()
|
||||||
fn GEPi(cx: @block_ctxt, base: ValueRef, ixs: [int]) -> ValueRef {
|
fn GEPi(cx: block, base: ValueRef, ixs: [int]) -> ValueRef {
|
||||||
let v: [ValueRef] = [];
|
let v: [ValueRef] = [];
|
||||||
for i: int in ixs { v += [C_i32(i as i32)]; }
|
for i: int in ixs { v += [C_i32(i as i32)]; }
|
||||||
ret InBoundsGEP(cx, base, v);
|
ret InBoundsGEP(cx, base, v);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn InBoundsGEP(cx: @block_ctxt, Pointer: ValueRef, Indices: [ValueRef]) ->
|
fn InBoundsGEP(cx: block, Pointer: ValueRef, Indices: [ValueRef]) ->
|
||||||
ValueRef {
|
ValueRef {
|
||||||
if cx.unreachable { ret llvm::LLVMGetUndef(T_ptr(T_nil())); }
|
if cx.unreachable { ret llvm::LLVMGetUndef(T_ptr(T_nil())); }
|
||||||
unsafe {
|
unsafe {
|
||||||
|
@ -353,142 +353,142 @@ fn InBoundsGEP(cx: @block_ctxt, Pointer: ValueRef, Indices: [ValueRef]) ->
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn StructGEP(cx: @block_ctxt, Pointer: ValueRef, Idx: uint) -> ValueRef {
|
fn StructGEP(cx: block, Pointer: ValueRef, Idx: uint) -> ValueRef {
|
||||||
if cx.unreachable { ret llvm::LLVMGetUndef(T_ptr(T_nil())); }
|
if cx.unreachable { ret llvm::LLVMGetUndef(T_ptr(T_nil())); }
|
||||||
ret llvm::LLVMBuildStructGEP(B(cx), Pointer, Idx as c_uint, noname());
|
ret llvm::LLVMBuildStructGEP(B(cx), Pointer, Idx as c_uint, noname());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn GlobalString(cx: @block_ctxt, _Str: sbuf) -> ValueRef {
|
fn GlobalString(cx: block, _Str: sbuf) -> ValueRef {
|
||||||
if cx.unreachable { ret llvm::LLVMGetUndef(T_ptr(T_i8())); }
|
if cx.unreachable { ret llvm::LLVMGetUndef(T_ptr(T_i8())); }
|
||||||
ret llvm::LLVMBuildGlobalString(B(cx), _Str, noname());
|
ret llvm::LLVMBuildGlobalString(B(cx), _Str, noname());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn GlobalStringPtr(cx: @block_ctxt, _Str: sbuf) -> ValueRef {
|
fn GlobalStringPtr(cx: block, _Str: sbuf) -> ValueRef {
|
||||||
if cx.unreachable { ret llvm::LLVMGetUndef(T_ptr(T_i8())); }
|
if cx.unreachable { ret llvm::LLVMGetUndef(T_ptr(T_i8())); }
|
||||||
ret llvm::LLVMBuildGlobalStringPtr(B(cx), _Str, noname());
|
ret llvm::LLVMBuildGlobalStringPtr(B(cx), _Str, noname());
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Casts */
|
/* Casts */
|
||||||
fn Trunc(cx: @block_ctxt, Val: ValueRef, DestTy: TypeRef) -> ValueRef {
|
fn Trunc(cx: block, Val: ValueRef, DestTy: TypeRef) -> ValueRef {
|
||||||
if cx.unreachable { ret llvm::LLVMGetUndef(DestTy); }
|
if cx.unreachable { ret llvm::LLVMGetUndef(DestTy); }
|
||||||
ret llvm::LLVMBuildTrunc(B(cx), Val, DestTy, noname());
|
ret llvm::LLVMBuildTrunc(B(cx), Val, DestTy, noname());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn ZExt(cx: @block_ctxt, Val: ValueRef, DestTy: TypeRef) -> ValueRef {
|
fn ZExt(cx: block, Val: ValueRef, DestTy: TypeRef) -> ValueRef {
|
||||||
if cx.unreachable { ret llvm::LLVMGetUndef(DestTy); }
|
if cx.unreachable { ret llvm::LLVMGetUndef(DestTy); }
|
||||||
ret llvm::LLVMBuildZExt(B(cx), Val, DestTy, noname());
|
ret llvm::LLVMBuildZExt(B(cx), Val, DestTy, noname());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn SExt(cx: @block_ctxt, Val: ValueRef, DestTy: TypeRef) -> ValueRef {
|
fn SExt(cx: block, Val: ValueRef, DestTy: TypeRef) -> ValueRef {
|
||||||
if cx.unreachable { ret llvm::LLVMGetUndef(DestTy); }
|
if cx.unreachable { ret llvm::LLVMGetUndef(DestTy); }
|
||||||
ret llvm::LLVMBuildSExt(B(cx), Val, DestTy, noname());
|
ret llvm::LLVMBuildSExt(B(cx), Val, DestTy, noname());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn FPToUI(cx: @block_ctxt, Val: ValueRef, DestTy: TypeRef) -> ValueRef {
|
fn FPToUI(cx: block, Val: ValueRef, DestTy: TypeRef) -> ValueRef {
|
||||||
if cx.unreachable { ret llvm::LLVMGetUndef(DestTy); }
|
if cx.unreachable { ret llvm::LLVMGetUndef(DestTy); }
|
||||||
ret llvm::LLVMBuildFPToUI(B(cx), Val, DestTy, noname());
|
ret llvm::LLVMBuildFPToUI(B(cx), Val, DestTy, noname());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn FPToSI(cx: @block_ctxt, Val: ValueRef, DestTy: TypeRef) -> ValueRef {
|
fn FPToSI(cx: block, Val: ValueRef, DestTy: TypeRef) -> ValueRef {
|
||||||
if cx.unreachable { ret llvm::LLVMGetUndef(DestTy); }
|
if cx.unreachable { ret llvm::LLVMGetUndef(DestTy); }
|
||||||
ret llvm::LLVMBuildFPToSI(B(cx), Val, DestTy, noname());
|
ret llvm::LLVMBuildFPToSI(B(cx), Val, DestTy, noname());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn UIToFP(cx: @block_ctxt, Val: ValueRef, DestTy: TypeRef) -> ValueRef {
|
fn UIToFP(cx: block, Val: ValueRef, DestTy: TypeRef) -> ValueRef {
|
||||||
if cx.unreachable { ret llvm::LLVMGetUndef(DestTy); }
|
if cx.unreachable { ret llvm::LLVMGetUndef(DestTy); }
|
||||||
ret llvm::LLVMBuildUIToFP(B(cx), Val, DestTy, noname());
|
ret llvm::LLVMBuildUIToFP(B(cx), Val, DestTy, noname());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn SIToFP(cx: @block_ctxt, Val: ValueRef, DestTy: TypeRef) -> ValueRef {
|
fn SIToFP(cx: block, Val: ValueRef, DestTy: TypeRef) -> ValueRef {
|
||||||
if cx.unreachable { ret llvm::LLVMGetUndef(DestTy); }
|
if cx.unreachable { ret llvm::LLVMGetUndef(DestTy); }
|
||||||
ret llvm::LLVMBuildSIToFP(B(cx), Val, DestTy, noname());
|
ret llvm::LLVMBuildSIToFP(B(cx), Val, DestTy, noname());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn FPTrunc(cx: @block_ctxt, Val: ValueRef, DestTy: TypeRef) -> ValueRef {
|
fn FPTrunc(cx: block, Val: ValueRef, DestTy: TypeRef) -> ValueRef {
|
||||||
if cx.unreachable { ret llvm::LLVMGetUndef(DestTy); }
|
if cx.unreachable { ret llvm::LLVMGetUndef(DestTy); }
|
||||||
ret llvm::LLVMBuildFPTrunc(B(cx), Val, DestTy, noname());
|
ret llvm::LLVMBuildFPTrunc(B(cx), Val, DestTy, noname());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn FPExt(cx: @block_ctxt, Val: ValueRef, DestTy: TypeRef) -> ValueRef {
|
fn FPExt(cx: block, Val: ValueRef, DestTy: TypeRef) -> ValueRef {
|
||||||
if cx.unreachable { ret llvm::LLVMGetUndef(DestTy); }
|
if cx.unreachable { ret llvm::LLVMGetUndef(DestTy); }
|
||||||
ret llvm::LLVMBuildFPExt(B(cx), Val, DestTy, noname());
|
ret llvm::LLVMBuildFPExt(B(cx), Val, DestTy, noname());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn PtrToInt(cx: @block_ctxt, Val: ValueRef, DestTy: TypeRef) -> ValueRef {
|
fn PtrToInt(cx: block, Val: ValueRef, DestTy: TypeRef) -> ValueRef {
|
||||||
if cx.unreachable { ret llvm::LLVMGetUndef(DestTy); }
|
if cx.unreachable { ret llvm::LLVMGetUndef(DestTy); }
|
||||||
ret llvm::LLVMBuildPtrToInt(B(cx), Val, DestTy, noname());
|
ret llvm::LLVMBuildPtrToInt(B(cx), Val, DestTy, noname());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn IntToPtr(cx: @block_ctxt, Val: ValueRef, DestTy: TypeRef) -> ValueRef {
|
fn IntToPtr(cx: block, Val: ValueRef, DestTy: TypeRef) -> ValueRef {
|
||||||
if cx.unreachable { ret llvm::LLVMGetUndef(DestTy); }
|
if cx.unreachable { ret llvm::LLVMGetUndef(DestTy); }
|
||||||
ret llvm::LLVMBuildIntToPtr(B(cx), Val, DestTy, noname());
|
ret llvm::LLVMBuildIntToPtr(B(cx), Val, DestTy, noname());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn BitCast(cx: @block_ctxt, Val: ValueRef, DestTy: TypeRef) -> ValueRef {
|
fn BitCast(cx: block, Val: ValueRef, DestTy: TypeRef) -> ValueRef {
|
||||||
if cx.unreachable { ret llvm::LLVMGetUndef(DestTy); }
|
if cx.unreachable { ret llvm::LLVMGetUndef(DestTy); }
|
||||||
ret llvm::LLVMBuildBitCast(B(cx), Val, DestTy, noname());
|
ret llvm::LLVMBuildBitCast(B(cx), Val, DestTy, noname());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn ZExtOrBitCast(cx: @block_ctxt, Val: ValueRef, DestTy: TypeRef) ->
|
fn ZExtOrBitCast(cx: block, Val: ValueRef, DestTy: TypeRef) ->
|
||||||
ValueRef {
|
ValueRef {
|
||||||
if cx.unreachable { ret llvm::LLVMGetUndef(DestTy); }
|
if cx.unreachable { ret llvm::LLVMGetUndef(DestTy); }
|
||||||
ret llvm::LLVMBuildZExtOrBitCast(B(cx), Val, DestTy, noname());
|
ret llvm::LLVMBuildZExtOrBitCast(B(cx), Val, DestTy, noname());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn SExtOrBitCast(cx: @block_ctxt, Val: ValueRef, DestTy: TypeRef) ->
|
fn SExtOrBitCast(cx: block, Val: ValueRef, DestTy: TypeRef) ->
|
||||||
ValueRef {
|
ValueRef {
|
||||||
if cx.unreachable { ret llvm::LLVMGetUndef(DestTy); }
|
if cx.unreachable { ret llvm::LLVMGetUndef(DestTy); }
|
||||||
ret llvm::LLVMBuildSExtOrBitCast(B(cx), Val, DestTy, noname());
|
ret llvm::LLVMBuildSExtOrBitCast(B(cx), Val, DestTy, noname());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn TruncOrBitCast(cx: @block_ctxt, Val: ValueRef, DestTy: TypeRef) ->
|
fn TruncOrBitCast(cx: block, Val: ValueRef, DestTy: TypeRef) ->
|
||||||
ValueRef {
|
ValueRef {
|
||||||
if cx.unreachable { ret llvm::LLVMGetUndef(DestTy); }
|
if cx.unreachable { ret llvm::LLVMGetUndef(DestTy); }
|
||||||
ret llvm::LLVMBuildTruncOrBitCast(B(cx), Val, DestTy, noname());
|
ret llvm::LLVMBuildTruncOrBitCast(B(cx), Val, DestTy, noname());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn Cast(cx: @block_ctxt, Op: Opcode, Val: ValueRef, DestTy: TypeRef,
|
fn Cast(cx: block, Op: Opcode, Val: ValueRef, DestTy: TypeRef,
|
||||||
_Name: sbuf) -> ValueRef {
|
_Name: sbuf) -> ValueRef {
|
||||||
if cx.unreachable { ret llvm::LLVMGetUndef(DestTy); }
|
if cx.unreachable { ret llvm::LLVMGetUndef(DestTy); }
|
||||||
ret llvm::LLVMBuildCast(B(cx), Op, Val, DestTy, noname());
|
ret llvm::LLVMBuildCast(B(cx), Op, Val, DestTy, noname());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn PointerCast(cx: @block_ctxt, Val: ValueRef, DestTy: TypeRef) -> ValueRef {
|
fn PointerCast(cx: block, Val: ValueRef, DestTy: TypeRef) -> ValueRef {
|
||||||
if cx.unreachable { ret llvm::LLVMGetUndef(DestTy); }
|
if cx.unreachable { ret llvm::LLVMGetUndef(DestTy); }
|
||||||
ret llvm::LLVMBuildPointerCast(B(cx), Val, DestTy, noname());
|
ret llvm::LLVMBuildPointerCast(B(cx), Val, DestTy, noname());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn IntCast(cx: @block_ctxt, Val: ValueRef, DestTy: TypeRef) -> ValueRef {
|
fn IntCast(cx: block, Val: ValueRef, DestTy: TypeRef) -> ValueRef {
|
||||||
if cx.unreachable { ret llvm::LLVMGetUndef(DestTy); }
|
if cx.unreachable { ret llvm::LLVMGetUndef(DestTy); }
|
||||||
ret llvm::LLVMBuildIntCast(B(cx), Val, DestTy, noname());
|
ret llvm::LLVMBuildIntCast(B(cx), Val, DestTy, noname());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn FPCast(cx: @block_ctxt, Val: ValueRef, DestTy: TypeRef) -> ValueRef {
|
fn FPCast(cx: block, Val: ValueRef, DestTy: TypeRef) -> ValueRef {
|
||||||
if cx.unreachable { ret llvm::LLVMGetUndef(DestTy); }
|
if cx.unreachable { ret llvm::LLVMGetUndef(DestTy); }
|
||||||
ret llvm::LLVMBuildFPCast(B(cx), Val, DestTy, noname());
|
ret llvm::LLVMBuildFPCast(B(cx), Val, DestTy, noname());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Comparisons */
|
/* Comparisons */
|
||||||
fn ICmp(cx: @block_ctxt, Op: IntPredicate, LHS: ValueRef, RHS: ValueRef)
|
fn ICmp(cx: block, Op: IntPredicate, LHS: ValueRef, RHS: ValueRef)
|
||||||
-> ValueRef {
|
-> ValueRef {
|
||||||
if cx.unreachable { ret llvm::LLVMGetUndef(T_i1()); }
|
if cx.unreachable { ret llvm::LLVMGetUndef(T_i1()); }
|
||||||
ret llvm::LLVMBuildICmp(B(cx), Op as c_uint, LHS, RHS, noname());
|
ret llvm::LLVMBuildICmp(B(cx), Op as c_uint, LHS, RHS, noname());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn FCmp(cx: @block_ctxt, Op: RealPredicate, LHS: ValueRef, RHS: ValueRef)
|
fn FCmp(cx: block, Op: RealPredicate, LHS: ValueRef, RHS: ValueRef)
|
||||||
-> ValueRef {
|
-> ValueRef {
|
||||||
if cx.unreachable { ret llvm::LLVMGetUndef(T_i1()); }
|
if cx.unreachable { ret llvm::LLVMGetUndef(T_i1()); }
|
||||||
ret llvm::LLVMBuildFCmp(B(cx), Op as c_uint, LHS, RHS, noname());
|
ret llvm::LLVMBuildFCmp(B(cx), Op as c_uint, LHS, RHS, noname());
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Miscellaneous instructions */
|
/* Miscellaneous instructions */
|
||||||
fn EmptyPhi(cx: @block_ctxt, Ty: TypeRef) -> ValueRef {
|
fn EmptyPhi(cx: block, Ty: TypeRef) -> ValueRef {
|
||||||
if cx.unreachable { ret llvm::LLVMGetUndef(Ty); }
|
if cx.unreachable { ret llvm::LLVMGetUndef(Ty); }
|
||||||
ret llvm::LLVMBuildPhi(B(cx), Ty, noname());
|
ret llvm::LLVMBuildPhi(B(cx), Ty, noname());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn Phi(cx: @block_ctxt, Ty: TypeRef, vals: [ValueRef], bbs: [BasicBlockRef])
|
fn Phi(cx: block, Ty: TypeRef, vals: [ValueRef], bbs: [BasicBlockRef])
|
||||||
-> ValueRef {
|
-> ValueRef {
|
||||||
if cx.unreachable { ret llvm::LLVMGetUndef(Ty); }
|
if cx.unreachable { ret llvm::LLVMGetUndef(Ty); }
|
||||||
assert vals.len() == bbs.len();
|
assert vals.len() == bbs.len();
|
||||||
|
@ -509,7 +509,7 @@ fn AddIncomingToPhi(phi: ValueRef, val: ValueRef, bb: BasicBlockRef) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn _UndefReturn(cx: @block_ctxt, Fn: ValueRef) -> ValueRef {
|
fn _UndefReturn(cx: block, Fn: ValueRef) -> ValueRef {
|
||||||
let ccx = cx.fcx.ccx;
|
let ccx = cx.fcx.ccx;
|
||||||
let ty = val_ty(Fn);
|
let ty = val_ty(Fn);
|
||||||
let retty = if llvm::LLVMGetTypeKind(ty) == 8 as c_int {
|
let retty = if llvm::LLVMGetTypeKind(ty) == 8 as c_int {
|
||||||
|
@ -517,7 +517,7 @@ fn _UndefReturn(cx: @block_ctxt, Fn: ValueRef) -> ValueRef {
|
||||||
ret llvm::LLVMGetUndef(retty);
|
ret llvm::LLVMGetUndef(retty);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn add_span_comment(bcx: @block_ctxt, sp: span, text: str) {
|
fn add_span_comment(bcx: block, sp: span, text: str) {
|
||||||
let ccx = bcx_ccx(bcx);
|
let ccx = bcx_ccx(bcx);
|
||||||
if (!ccx.sess.opts.no_asm_comments) {
|
if (!ccx.sess.opts.no_asm_comments) {
|
||||||
let s = text + " (" + codemap::span_to_str(sp, ccx.sess.codemap)
|
let s = text + " (" + codemap::span_to_str(sp, ccx.sess.codemap)
|
||||||
|
@ -527,7 +527,7 @@ fn add_span_comment(bcx: @block_ctxt, sp: span, text: str) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn add_comment(bcx: @block_ctxt, text: str) {
|
fn add_comment(bcx: block, text: str) {
|
||||||
let ccx = bcx_ccx(bcx);
|
let ccx = bcx_ccx(bcx);
|
||||||
if (!ccx.sess.opts.no_asm_comments) {
|
if (!ccx.sess.opts.no_asm_comments) {
|
||||||
check str::is_not_empty("$");
|
check str::is_not_empty("$");
|
||||||
|
@ -543,7 +543,7 @@ fn add_comment(bcx: @block_ctxt, text: str) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn Call(cx: @block_ctxt, Fn: ValueRef, Args: [ValueRef]) -> ValueRef {
|
fn Call(cx: block, Fn: ValueRef, Args: [ValueRef]) -> ValueRef {
|
||||||
if cx.unreachable { ret _UndefReturn(cx, Fn); }
|
if cx.unreachable { ret _UndefReturn(cx, Fn); }
|
||||||
unsafe {
|
unsafe {
|
||||||
ret llvm::LLVMBuildCall(B(cx), Fn, vec::to_ptr(Args),
|
ret llvm::LLVMBuildCall(B(cx), Fn, vec::to_ptr(Args),
|
||||||
|
@ -551,7 +551,7 @@ fn Call(cx: @block_ctxt, Fn: ValueRef, Args: [ValueRef]) -> ValueRef {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn FastCall(cx: @block_ctxt, Fn: ValueRef, Args: [ValueRef]) -> ValueRef {
|
fn FastCall(cx: block, Fn: ValueRef, Args: [ValueRef]) -> ValueRef {
|
||||||
if cx.unreachable { ret _UndefReturn(cx, Fn); }
|
if cx.unreachable { ret _UndefReturn(cx, Fn); }
|
||||||
unsafe {
|
unsafe {
|
||||||
let v = llvm::LLVMBuildCall(B(cx), Fn, vec::to_ptr(Args),
|
let v = llvm::LLVMBuildCall(B(cx), Fn, vec::to_ptr(Args),
|
||||||
|
@ -561,7 +561,7 @@ fn FastCall(cx: @block_ctxt, Fn: ValueRef, Args: [ValueRef]) -> ValueRef {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn CallWithConv(cx: @block_ctxt, Fn: ValueRef, Args: [ValueRef],
|
fn CallWithConv(cx: block, Fn: ValueRef, Args: [ValueRef],
|
||||||
Conv: CallConv) -> ValueRef {
|
Conv: CallConv) -> ValueRef {
|
||||||
if cx.unreachable { ret _UndefReturn(cx, Fn); }
|
if cx.unreachable { ret _UndefReturn(cx, Fn); }
|
||||||
unsafe {
|
unsafe {
|
||||||
|
@ -572,64 +572,64 @@ fn CallWithConv(cx: @block_ctxt, Fn: ValueRef, Args: [ValueRef],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn Select(cx: @block_ctxt, If: ValueRef, Then: ValueRef, Else: ValueRef) ->
|
fn Select(cx: block, If: ValueRef, Then: ValueRef, Else: ValueRef) ->
|
||||||
ValueRef {
|
ValueRef {
|
||||||
if cx.unreachable { ret _Undef(Then); }
|
if cx.unreachable { ret _Undef(Then); }
|
||||||
ret llvm::LLVMBuildSelect(B(cx), If, Then, Else, noname());
|
ret llvm::LLVMBuildSelect(B(cx), If, Then, Else, noname());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn VAArg(cx: @block_ctxt, list: ValueRef, Ty: TypeRef) -> ValueRef {
|
fn VAArg(cx: block, list: ValueRef, Ty: TypeRef) -> ValueRef {
|
||||||
if cx.unreachable { ret llvm::LLVMGetUndef(Ty); }
|
if cx.unreachable { ret llvm::LLVMGetUndef(Ty); }
|
||||||
ret llvm::LLVMBuildVAArg(B(cx), list, Ty, noname());
|
ret llvm::LLVMBuildVAArg(B(cx), list, Ty, noname());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn ExtractElement(cx: @block_ctxt, VecVal: ValueRef, Index: ValueRef) ->
|
fn ExtractElement(cx: block, VecVal: ValueRef, Index: ValueRef) ->
|
||||||
ValueRef {
|
ValueRef {
|
||||||
if cx.unreachable { ret llvm::LLVMGetUndef(T_nil()); }
|
if cx.unreachable { ret llvm::LLVMGetUndef(T_nil()); }
|
||||||
ret llvm::LLVMBuildExtractElement(B(cx), VecVal, Index, noname());
|
ret llvm::LLVMBuildExtractElement(B(cx), VecVal, Index, noname());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn InsertElement(cx: @block_ctxt, VecVal: ValueRef, EltVal: ValueRef,
|
fn InsertElement(cx: block, VecVal: ValueRef, EltVal: ValueRef,
|
||||||
Index: ValueRef) {
|
Index: ValueRef) {
|
||||||
if cx.unreachable { ret; }
|
if cx.unreachable { ret; }
|
||||||
llvm::LLVMBuildInsertElement(B(cx), VecVal, EltVal, Index, noname());
|
llvm::LLVMBuildInsertElement(B(cx), VecVal, EltVal, Index, noname());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn ShuffleVector(cx: @block_ctxt, V1: ValueRef, V2: ValueRef,
|
fn ShuffleVector(cx: block, V1: ValueRef, V2: ValueRef,
|
||||||
Mask: ValueRef) {
|
Mask: ValueRef) {
|
||||||
if cx.unreachable { ret; }
|
if cx.unreachable { ret; }
|
||||||
llvm::LLVMBuildShuffleVector(B(cx), V1, V2, Mask, noname());
|
llvm::LLVMBuildShuffleVector(B(cx), V1, V2, Mask, noname());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn ExtractValue(cx: @block_ctxt, AggVal: ValueRef, Index: uint) -> ValueRef {
|
fn ExtractValue(cx: block, AggVal: ValueRef, Index: uint) -> ValueRef {
|
||||||
if cx.unreachable { ret llvm::LLVMGetUndef(T_nil()); }
|
if cx.unreachable { ret llvm::LLVMGetUndef(T_nil()); }
|
||||||
ret llvm::LLVMBuildExtractValue(B(cx), AggVal, Index as c_uint, noname());
|
ret llvm::LLVMBuildExtractValue(B(cx), AggVal, Index as c_uint, noname());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn InsertValue(cx: @block_ctxt, AggVal: ValueRef, EltVal: ValueRef,
|
fn InsertValue(cx: block, AggVal: ValueRef, EltVal: ValueRef,
|
||||||
Index: uint) {
|
Index: uint) {
|
||||||
if cx.unreachable { ret; }
|
if cx.unreachable { ret; }
|
||||||
llvm::LLVMBuildInsertValue(B(cx), AggVal, EltVal, Index as c_uint,
|
llvm::LLVMBuildInsertValue(B(cx), AggVal, EltVal, Index as c_uint,
|
||||||
noname());
|
noname());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn IsNull(cx: @block_ctxt, Val: ValueRef) -> ValueRef {
|
fn IsNull(cx: block, Val: ValueRef) -> ValueRef {
|
||||||
if cx.unreachable { ret llvm::LLVMGetUndef(T_i1()); }
|
if cx.unreachable { ret llvm::LLVMGetUndef(T_i1()); }
|
||||||
ret llvm::LLVMBuildIsNull(B(cx), Val, noname());
|
ret llvm::LLVMBuildIsNull(B(cx), Val, noname());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn IsNotNull(cx: @block_ctxt, Val: ValueRef) -> ValueRef {
|
fn IsNotNull(cx: block, Val: ValueRef) -> ValueRef {
|
||||||
if cx.unreachable { ret llvm::LLVMGetUndef(T_i1()); }
|
if cx.unreachable { ret llvm::LLVMGetUndef(T_i1()); }
|
||||||
ret llvm::LLVMBuildIsNotNull(B(cx), Val, noname());
|
ret llvm::LLVMBuildIsNotNull(B(cx), Val, noname());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn PtrDiff(cx: @block_ctxt, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
|
fn PtrDiff(cx: block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
|
||||||
let ccx = cx.fcx.ccx;
|
let ccx = cx.fcx.ccx;
|
||||||
if cx.unreachable { ret llvm::LLVMGetUndef(ccx.int_type); }
|
if cx.unreachable { ret llvm::LLVMGetUndef(ccx.int_type); }
|
||||||
ret llvm::LLVMBuildPtrDiff(B(cx), LHS, RHS, noname());
|
ret llvm::LLVMBuildPtrDiff(B(cx), LHS, RHS, noname());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn Trap(cx: @block_ctxt) {
|
fn Trap(cx: block) {
|
||||||
if cx.unreachable { ret; }
|
if cx.unreachable { ret; }
|
||||||
let b = B(cx);
|
let b = B(cx);
|
||||||
let BB: BasicBlockRef = llvm::LLVMGetInsertBlock(b);
|
let BB: BasicBlockRef = llvm::LLVMGetInsertBlock(b);
|
||||||
|
@ -646,18 +646,18 @@ fn Trap(cx: @block_ctxt) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn LandingPad(cx: @block_ctxt, Ty: TypeRef, PersFn: ValueRef,
|
fn LandingPad(cx: block, Ty: TypeRef, PersFn: ValueRef,
|
||||||
NumClauses: uint) -> ValueRef {
|
NumClauses: uint) -> ValueRef {
|
||||||
assert !cx.terminated && !cx.unreachable;
|
assert !cx.terminated && !cx.unreachable;
|
||||||
ret llvm::LLVMBuildLandingPad(B(cx), Ty, PersFn,
|
ret llvm::LLVMBuildLandingPad(B(cx), Ty, PersFn,
|
||||||
NumClauses as c_uint, noname());
|
NumClauses as c_uint, noname());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn SetCleanup(_cx: @block_ctxt, LandingPad: ValueRef) {
|
fn SetCleanup(_cx: block, LandingPad: ValueRef) {
|
||||||
llvm::LLVMSetCleanup(LandingPad, lib::llvm::True);
|
llvm::LLVMSetCleanup(LandingPad, lib::llvm::True);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn Resume(cx: @block_ctxt, Exn: ValueRef) -> ValueRef {
|
fn Resume(cx: block, Exn: ValueRef) -> ValueRef {
|
||||||
assert (!cx.terminated);
|
assert (!cx.terminated);
|
||||||
cx.terminated = true;
|
cx.terminated = true;
|
||||||
ret llvm::LLVMBuildResume(B(cx), Exn);
|
ret llvm::LLVMBuildResume(B(cx), Exn);
|
||||||
|
|
|
@ -162,15 +162,15 @@ fn mk_closure_tys(tcx: ty::ctxt,
|
||||||
ret (cdata_ty, bound_tys);
|
ret (cdata_ty, bound_tys);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn allocate_cbox(bcx: @block_ctxt,
|
fn allocate_cbox(bcx: block,
|
||||||
ck: ty::closure_kind,
|
ck: ty::closure_kind,
|
||||||
cdata_ty: ty::t)
|
cdata_ty: ty::t)
|
||||||
-> (@block_ctxt, ValueRef, [ValueRef]) {
|
-> (block, ValueRef, [ValueRef]) {
|
||||||
|
|
||||||
// let ccx = bcx_ccx(bcx);
|
// let ccx = bcx_ccx(bcx);
|
||||||
let ccx = bcx_ccx(bcx), tcx = ccx.tcx;
|
let ccx = bcx_ccx(bcx), tcx = ccx.tcx;
|
||||||
|
|
||||||
fn nuke_ref_count(bcx: @block_ctxt, box: ValueRef) {
|
fn nuke_ref_count(bcx: block, box: ValueRef) {
|
||||||
// Initialize ref count to arbitrary value for debugging:
|
// Initialize ref count to arbitrary value for debugging:
|
||||||
let ccx = bcx_ccx(bcx);
|
let ccx = bcx_ccx(bcx);
|
||||||
let box = PointerCast(bcx, box, T_opaque_box_ptr(ccx));
|
let box = PointerCast(bcx, box, T_opaque_box_ptr(ccx));
|
||||||
|
@ -179,10 +179,10 @@ fn allocate_cbox(bcx: @block_ctxt,
|
||||||
Store(bcx, rc, ref_cnt);
|
Store(bcx, rc, ref_cnt);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn store_uniq_tydesc(bcx: @block_ctxt,
|
fn store_uniq_tydesc(bcx: block,
|
||||||
cdata_ty: ty::t,
|
cdata_ty: ty::t,
|
||||||
box: ValueRef,
|
box: ValueRef,
|
||||||
&ti: option::t<@tydesc_info>) -> @block_ctxt {
|
&ti: option::t<@tydesc_info>) -> block {
|
||||||
let ccx = bcx_ccx(bcx);
|
let ccx = bcx_ccx(bcx);
|
||||||
let bound_tydesc = GEPi(bcx, box, [0, abi::box_field_tydesc]);
|
let bound_tydesc = GEPi(bcx, box, [0, abi::box_field_tydesc]);
|
||||||
let {bcx, val: td} = base::get_tydesc(bcx, cdata_ty, true, ti);
|
let {bcx, val: td} = base::get_tydesc(bcx, cdata_ty, true, ti);
|
||||||
|
@ -224,10 +224,10 @@ fn allocate_cbox(bcx: @block_ctxt,
|
||||||
type closure_result = {
|
type closure_result = {
|
||||||
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_ctxt // final bcx
|
bcx: block // final bcx
|
||||||
};
|
};
|
||||||
|
|
||||||
fn cast_if_we_can(bcx: @block_ctxt, llbox: ValueRef, t: ty::t) -> ValueRef {
|
fn cast_if_we_can(bcx: block, llbox: ValueRef, t: ty::t) -> ValueRef {
|
||||||
let ccx = bcx_ccx(bcx);
|
let ccx = bcx_ccx(bcx);
|
||||||
if check type_has_static_size(ccx, t) {
|
if check type_has_static_size(ccx, t) {
|
||||||
let llty = type_of(ccx, t);
|
let llty = type_of(ccx, t);
|
||||||
|
@ -242,12 +242,12 @@ fn cast_if_we_can(bcx: @block_ctxt, llbox: ValueRef, t: ty::t) -> ValueRef {
|
||||||
// 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.
|
||||||
fn store_environment(
|
fn store_environment(
|
||||||
bcx: @block_ctxt, lltyparams: [fn_ty_param],
|
bcx: block, lltyparams: [fn_ty_param],
|
||||||
bound_values: [environment_value],
|
bound_values: [environment_value],
|
||||||
ck: ty::closure_kind)
|
ck: ty::closure_kind)
|
||||||
-> closure_result {
|
-> closure_result {
|
||||||
|
|
||||||
fn maybe_clone_tydesc(bcx: @block_ctxt,
|
fn maybe_clone_tydesc(bcx: block,
|
||||||
ck: ty::closure_kind,
|
ck: ty::closure_kind,
|
||||||
td: ValueRef) -> ValueRef {
|
td: ValueRef) -> ValueRef {
|
||||||
ret alt ck {
|
ret alt ck {
|
||||||
|
@ -349,7 +349,7 @@ fn store_environment(
|
||||||
|
|
||||||
// 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.
|
||||||
fn build_closure(bcx0: @block_ctxt,
|
fn build_closure(bcx0: block,
|
||||||
cap_vars: [capture::capture_var],
|
cap_vars: [capture::capture_var],
|
||||||
ck: ty::closure_kind)
|
ck: ty::closure_kind)
|
||||||
-> closure_result {
|
-> closure_result {
|
||||||
|
@ -386,12 +386,12 @@ fn build_closure(bcx0: @block_ctxt,
|
||||||
// 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.
|
||||||
fn load_environment(enclosing_cx: @block_ctxt,
|
fn load_environment(enclosing_cx: block,
|
||||||
fcx: @fn_ctxt,
|
fcx: @fn_ctxt,
|
||||||
cdata_ty: ty::t,
|
cdata_ty: ty::t,
|
||||||
cap_vars: [capture::capture_var],
|
cap_vars: [capture::capture_var],
|
||||||
ck: ty::closure_kind) {
|
ck: ty::closure_kind) {
|
||||||
let bcx = new_raw_block_ctxt(fcx, fcx.llloadenv);
|
let bcx = raw_block(fcx, fcx.llloadenv);
|
||||||
|
|
||||||
// Load a pointer to the closure data, skipping over the box header:
|
// Load a pointer to the closure data, skipping over the box header:
|
||||||
let llcdata = base::opaque_box_body(bcx, cdata_ty, fcx.llenv);
|
let llcdata = base::opaque_box_body(bcx, cdata_ty, fcx.llenv);
|
||||||
|
@ -440,14 +440,14 @@ fn load_environment(enclosing_cx: @block_ctxt,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn trans_expr_fn(bcx: @block_ctxt,
|
fn trans_expr_fn(bcx: block,
|
||||||
proto: ast::proto,
|
proto: ast::proto,
|
||||||
decl: ast::fn_decl,
|
decl: ast::fn_decl,
|
||||||
body: ast::blk,
|
body: ast::blk,
|
||||||
sp: span,
|
sp: span,
|
||||||
id: ast::node_id,
|
id: ast::node_id,
|
||||||
cap_clause: ast::capture_clause,
|
cap_clause: ast::capture_clause,
|
||||||
dest: dest) -> @block_ctxt {
|
dest: dest) -> block {
|
||||||
if dest == ignore { ret bcx; }
|
if dest == ignore { ret bcx; }
|
||||||
let ccx = bcx_ccx(bcx), bcx = bcx;
|
let ccx = bcx_ccx(bcx), bcx = bcx;
|
||||||
let fty = node_id_type(bcx, id);
|
let fty = node_id_type(bcx, id);
|
||||||
|
@ -482,17 +482,17 @@ fn trans_expr_fn(bcx: @block_ctxt,
|
||||||
ret bcx;
|
ret bcx;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn trans_bind(cx: @block_ctxt, f: @ast::expr, args: [option<@ast::expr>],
|
fn trans_bind(cx: block, f: @ast::expr, args: [option<@ast::expr>],
|
||||||
id: ast::node_id, dest: dest) -> @block_ctxt {
|
id: ast::node_id, dest: dest) -> block {
|
||||||
let f_res = trans_callee(cx, f);
|
let f_res = trans_callee(cx, f);
|
||||||
ret trans_bind_1(cx, expr_ty(cx, f), f_res, args,
|
ret trans_bind_1(cx, expr_ty(cx, f), f_res, args,
|
||||||
node_id_type(cx, id), dest);
|
node_id_type(cx, id), dest);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn trans_bind_1(cx: @block_ctxt, outgoing_fty: ty::t,
|
fn trans_bind_1(cx: block, outgoing_fty: ty::t,
|
||||||
f_res: lval_maybe_callee,
|
f_res: lval_maybe_callee,
|
||||||
args: [option<@ast::expr>], pair_ty: ty::t,
|
args: [option<@ast::expr>], pair_ty: ty::t,
|
||||||
dest: dest) -> @block_ctxt {
|
dest: dest) -> block {
|
||||||
let ccx = bcx_ccx(cx);
|
let ccx = bcx_ccx(cx);
|
||||||
let bound: [@ast::expr] = [];
|
let bound: [@ast::expr] = [];
|
||||||
for argopt: option<@ast::expr> in args {
|
for argopt: option<@ast::expr> in args {
|
||||||
|
@ -572,33 +572,19 @@ fn trans_bind_1(cx: @block_ctxt, outgoing_fty: ty::t,
|
||||||
ret bcx;
|
ret bcx;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn make_null_test(
|
|
||||||
in_bcx: @block_ctxt,
|
|
||||||
ptr: ValueRef,
|
|
||||||
blk: fn(@block_ctxt) -> @block_ctxt)
|
|
||||||
-> @block_ctxt {
|
|
||||||
let not_null_bcx = new_sub_block_ctxt(in_bcx, "not null");
|
|
||||||
let next_bcx = new_sub_block_ctxt(in_bcx, "next");
|
|
||||||
let null_test = IsNull(in_bcx, ptr);
|
|
||||||
CondBr(in_bcx, null_test, next_bcx.llbb, not_null_bcx.llbb);
|
|
||||||
let not_null_bcx = blk(not_null_bcx);
|
|
||||||
Br(not_null_bcx, next_bcx.llbb);
|
|
||||||
ret next_bcx;
|
|
||||||
}
|
|
||||||
|
|
||||||
fn make_fn_glue(
|
fn make_fn_glue(
|
||||||
cx: @block_ctxt,
|
cx: block,
|
||||||
v: ValueRef,
|
v: ValueRef,
|
||||||
t: ty::t,
|
t: ty::t,
|
||||||
glue_fn: fn@(@block_ctxt, v: ValueRef, t: ty::t) -> @block_ctxt)
|
glue_fn: fn@(block, v: ValueRef, t: ty::t) -> block)
|
||||||
-> @block_ctxt {
|
-> block {
|
||||||
let bcx = cx;
|
let bcx = cx;
|
||||||
let tcx = bcx_tcx(cx);
|
let tcx = bcx_tcx(cx);
|
||||||
|
|
||||||
let fn_env = fn@(ck: ty::closure_kind) -> @block_ctxt {
|
let fn_env = fn@(ck: ty::closure_kind) -> block {
|
||||||
let box_cell_v = GEPi(cx, v, [0, abi::fn_field_box]);
|
let box_cell_v = GEPi(cx, v, [0, abi::fn_field_box]);
|
||||||
let box_ptr_v = Load(cx, box_cell_v);
|
let box_ptr_v = Load(cx, box_cell_v);
|
||||||
make_null_test(cx, box_ptr_v) {|bcx|
|
with_cond(cx, IsNotNull(cx, box_ptr_v)) {|bcx|
|
||||||
let closure_ty = ty::mk_opaque_closure_ptr(tcx, ck);
|
let closure_ty = ty::mk_opaque_closure_ptr(tcx, ck);
|
||||||
glue_fn(bcx, box_cell_v, closure_ty)
|
glue_fn(bcx, box_cell_v, closure_ty)
|
||||||
}
|
}
|
||||||
|
@ -615,10 +601,10 @@ fn make_fn_glue(
|
||||||
}
|
}
|
||||||
|
|
||||||
fn make_opaque_cbox_take_glue(
|
fn make_opaque_cbox_take_glue(
|
||||||
bcx: @block_ctxt,
|
bcx: block,
|
||||||
ck: ty::closure_kind,
|
ck: ty::closure_kind,
|
||||||
cboxptr: ValueRef) // ptr to ptr to the opaque closure
|
cboxptr: ValueRef) // ptr to ptr to the opaque closure
|
||||||
-> @block_ctxt {
|
-> block {
|
||||||
// Easy cases:
|
// Easy cases:
|
||||||
alt ck {
|
alt ck {
|
||||||
ty::ck_block { ret bcx; }
|
ty::ck_block { ret bcx; }
|
||||||
|
@ -631,7 +617,7 @@ fn make_opaque_cbox_take_glue(
|
||||||
let tcx = bcx_tcx(bcx);
|
let tcx = bcx_tcx(bcx);
|
||||||
let llopaquecboxty = T_opaque_box_ptr(ccx);
|
let llopaquecboxty = T_opaque_box_ptr(ccx);
|
||||||
let cbox_in = Load(bcx, cboxptr);
|
let cbox_in = Load(bcx, cboxptr);
|
||||||
make_null_test(bcx, cbox_in) {|bcx|
|
with_cond(bcx, IsNotNull(bcx, cbox_in)) {|bcx|
|
||||||
// Load the size from the type descr found in the cbox
|
// Load the size from the type descr found in the cbox
|
||||||
let cbox_in = PointerCast(bcx, cbox_in, llopaquecboxty);
|
let cbox_in = PointerCast(bcx, cbox_in, llopaquecboxty);
|
||||||
let tydescptr = GEPi(bcx, cbox_in, [0, abi::box_field_tydesc]);
|
let tydescptr = GEPi(bcx, cbox_in, [0, abi::box_field_tydesc]);
|
||||||
|
@ -663,10 +649,10 @@ fn make_opaque_cbox_take_glue(
|
||||||
}
|
}
|
||||||
|
|
||||||
fn make_opaque_cbox_drop_glue(
|
fn make_opaque_cbox_drop_glue(
|
||||||
bcx: @block_ctxt,
|
bcx: block,
|
||||||
ck: ty::closure_kind,
|
ck: ty::closure_kind,
|
||||||
cboxptr: ValueRef) // ptr to the opaque closure
|
cboxptr: ValueRef) // ptr to the opaque closure
|
||||||
-> @block_ctxt {
|
-> block {
|
||||||
alt ck {
|
alt ck {
|
||||||
ty::ck_block { bcx }
|
ty::ck_block { bcx }
|
||||||
ty::ck_box {
|
ty::ck_box {
|
||||||
|
@ -681,10 +667,10 @@ fn make_opaque_cbox_drop_glue(
|
||||||
}
|
}
|
||||||
|
|
||||||
fn make_opaque_cbox_free_glue(
|
fn make_opaque_cbox_free_glue(
|
||||||
bcx: @block_ctxt,
|
bcx: block,
|
||||||
ck: ty::closure_kind,
|
ck: ty::closure_kind,
|
||||||
cbox: ValueRef) // ptr to the opaque closure
|
cbox: ValueRef) // ptr to the opaque closure
|
||||||
-> @block_ctxt {
|
-> block {
|
||||||
alt ck {
|
alt ck {
|
||||||
ty::ck_block { ret bcx; }
|
ty::ck_block { ret bcx; }
|
||||||
ty::ck_box | ty::ck_uniq { /* hard cases: */ }
|
ty::ck_box | ty::ck_uniq { /* hard cases: */ }
|
||||||
|
@ -692,7 +678,7 @@ fn make_opaque_cbox_free_glue(
|
||||||
|
|
||||||
let ccx = bcx_ccx(bcx);
|
let ccx = bcx_ccx(bcx);
|
||||||
let tcx = bcx_tcx(bcx);
|
let tcx = bcx_tcx(bcx);
|
||||||
make_null_test(bcx, cbox) {|bcx|
|
with_cond(bcx, IsNotNull(bcx, cbox)) {|bcx|
|
||||||
// Load the type descr found in the cbox
|
// Load the type descr found in the cbox
|
||||||
let lltydescty = T_ptr(ccx.tydesc_type);
|
let lltydescty = T_ptr(ccx.tydesc_type);
|
||||||
let cbox = PointerCast(bcx, cbox, T_opaque_cbox_ptr(ccx));
|
let cbox = PointerCast(bcx, cbox, T_opaque_cbox_ptr(ccx));
|
||||||
|
@ -783,13 +769,13 @@ fn trans_bind_thunk(ccx: @crate_ctxt,
|
||||||
// Create a new function context and block context for the thunk, and hold
|
// Create a new function context and block context for the thunk, and hold
|
||||||
// onto a pointer to the first block in the function for later use.
|
// onto a pointer to the first block in the function for later use.
|
||||||
let fcx = new_fn_ctxt(ccx, path, llthunk, none);
|
let fcx = new_fn_ctxt(ccx, path, llthunk, none);
|
||||||
let bcx = new_top_block_ctxt(fcx, none);
|
let bcx = top_scope_block(fcx, none);
|
||||||
let lltop = bcx.llbb;
|
let lltop = bcx.llbb;
|
||||||
// Since we might need to construct derived tydescs that depend on
|
// Since we might need to construct derived tydescs that depend on
|
||||||
// our bound tydescs, we need to load tydescs out of the environment
|
// our bound tydescs, we need to load tydescs out of the environment
|
||||||
// before derived tydescs are constructed. To do this, we load them
|
// before derived tydescs are constructed. To do this, we load them
|
||||||
// in the load_env block.
|
// in the load_env block.
|
||||||
let l_bcx = new_raw_block_ctxt(fcx, fcx.llloadenv);
|
let l_bcx = raw_block(fcx, fcx.llloadenv);
|
||||||
|
|
||||||
// The 'llenv' that will arrive in the thunk we're creating is an
|
// The 'llenv' that will arrive in the thunk we're creating is an
|
||||||
// environment that will contain the values of its arguments and a
|
// environment that will contain the values of its arguments and a
|
||||||
|
|
|
@ -218,8 +218,8 @@ fn warn_not_to_commit(ccx: @crate_ctxt, msg: str) {
|
||||||
}
|
}
|
||||||
|
|
||||||
enum cleanup {
|
enum cleanup {
|
||||||
clean(fn@(@block_ctxt) -> @block_ctxt),
|
clean(fn@(block) -> block),
|
||||||
clean_temp(ValueRef, fn@(@block_ctxt) -> @block_ctxt),
|
clean_temp(ValueRef, fn@(block) -> block),
|
||||||
}
|
}
|
||||||
|
|
||||||
// Used to remember and reuse existing cleanup paths
|
// Used to remember and reuse existing cleanup paths
|
||||||
|
@ -232,17 +232,17 @@ fn scope_clean_changed(info: scope_info) {
|
||||||
info.landing_pad = none;
|
info.landing_pad = none;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn add_clean(cx: @block_ctxt, val: ValueRef, ty: ty::t) {
|
fn add_clean(cx: block, val: ValueRef, ty: ty::t) {
|
||||||
if !ty::type_needs_drop(bcx_tcx(cx), ty) { ret; }
|
if !ty::type_needs_drop(bcx_tcx(cx), ty) { ret; }
|
||||||
in_scope_cx(cx) {|info|
|
in_scope_cx(cx) {|info|
|
||||||
info.cleanups += [clean(bind drop_ty(_, val, ty))];
|
info.cleanups += [clean(bind drop_ty(_, val, ty))];
|
||||||
scope_clean_changed(info);
|
scope_clean_changed(info);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn add_clean_temp(cx: @block_ctxt, val: ValueRef, ty: ty::t) {
|
fn add_clean_temp(cx: block, val: ValueRef, ty: ty::t) {
|
||||||
if !ty::type_needs_drop(bcx_tcx(cx), ty) { ret; }
|
if !ty::type_needs_drop(bcx_tcx(cx), ty) { ret; }
|
||||||
fn do_drop(bcx: @block_ctxt, val: ValueRef, ty: ty::t) ->
|
fn do_drop(bcx: block, val: ValueRef, ty: ty::t) ->
|
||||||
@block_ctxt {
|
block {
|
||||||
if ty::type_is_immediate(ty) {
|
if ty::type_is_immediate(ty) {
|
||||||
ret base::drop_ty_immediate(bcx, val, ty);
|
ret base::drop_ty_immediate(bcx, val, ty);
|
||||||
} else {
|
} else {
|
||||||
|
@ -254,14 +254,14 @@ fn add_clean_temp(cx: @block_ctxt, val: ValueRef, ty: ty::t) {
|
||||||
scope_clean_changed(info);
|
scope_clean_changed(info);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn add_clean_temp_mem(cx: @block_ctxt, val: ValueRef, ty: ty::t) {
|
fn add_clean_temp_mem(cx: block, val: ValueRef, ty: ty::t) {
|
||||||
if !ty::type_needs_drop(bcx_tcx(cx), ty) { ret; }
|
if !ty::type_needs_drop(bcx_tcx(cx), ty) { ret; }
|
||||||
in_scope_cx(cx) {|info|
|
in_scope_cx(cx) {|info|
|
||||||
info.cleanups += [clean_temp(val, bind drop_ty(_, val, ty))];
|
info.cleanups += [clean_temp(val, bind drop_ty(_, val, ty))];
|
||||||
scope_clean_changed(info);
|
scope_clean_changed(info);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn add_clean_free(cx: @block_ctxt, ptr: ValueRef, shared: bool) {
|
fn add_clean_free(cx: block, ptr: ValueRef, shared: bool) {
|
||||||
let free_fn = if shared { bind base::trans_shared_free(_, ptr) }
|
let free_fn = if shared { bind base::trans_shared_free(_, ptr) }
|
||||||
else { bind base::trans_free(_, ptr) };
|
else { bind base::trans_free(_, ptr) };
|
||||||
in_scope_cx(cx) {|info|
|
in_scope_cx(cx) {|info|
|
||||||
|
@ -274,7 +274,7 @@ fn add_clean_free(cx: @block_ctxt, ptr: ValueRef, shared: bool) {
|
||||||
// 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.
|
||||||
fn revoke_clean(cx: @block_ctxt, val: ValueRef) {
|
fn revoke_clean(cx: block, val: ValueRef) {
|
||||||
in_scope_cx(cx) {|info|
|
in_scope_cx(cx) {|info|
|
||||||
let i = 0u;
|
let i = 0u;
|
||||||
for cu in info.cleanups {
|
for cu in info.cleanups {
|
||||||
|
@ -317,18 +317,18 @@ enum block_kind {
|
||||||
// cleaned up. May correspond to an actual block in the language, but also
|
// cleaned up. May correspond to an actual block in the language, but also
|
||||||
// to an implicit scope, for example, calls introduce an implicit scope in
|
// to an implicit scope, for example, calls introduce an implicit scope in
|
||||||
// which the arguments are evaluated and cleaned up.
|
// which the arguments are evaluated and cleaned up.
|
||||||
scope_block(scope_info),
|
block_scope(scope_info),
|
||||||
// A non-scope block is a basic block created as a translation artifact
|
// A non-scope block is a basic block created as a translation artifact
|
||||||
// from translating code that expresses conditional logic rather than by
|
// from translating code that expresses conditional logic rather than by
|
||||||
// explicit { ... } block structure in the source language. It's called a
|
// explicit { ... } block structure in the source language. It's called a
|
||||||
// non-scope block because it doesn't introduce a new variable scope.
|
// non-scope block because it doesn't introduce a new variable scope.
|
||||||
non_scope_block,
|
block_non_scope,
|
||||||
}
|
}
|
||||||
|
|
||||||
enum loop_cont { cont_self, cont_other(@block_ctxt), }
|
enum loop_cont { cont_self, cont_other(block), }
|
||||||
|
|
||||||
type scope_info = {
|
type scope_info = {
|
||||||
is_loop: option<{cnt: loop_cont, brk: @block_ctxt}>,
|
is_loop: option<{cnt: loop_cont, brk: block}>,
|
||||||
// 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
|
||||||
// block.
|
// block.
|
||||||
|
@ -345,7 +345,7 @@ type scope_info = {
|
||||||
// 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.
|
||||||
type block_ctxt = {
|
type block = @{
|
||||||
// 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
|
||||||
|
@ -359,7 +359,7 @@ type block_ctxt = {
|
||||||
kind: block_kind,
|
kind: block_kind,
|
||||||
// The source span where the block came from, if it is a block that
|
// The source span where the block came from, if it is a block that
|
||||||
// actually appears in the source code.
|
// actually appears in the source code.
|
||||||
block_span: option<span>,
|
mutable block_span: option<span>,
|
||||||
// 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: @fn_ctxt
|
fcx: @fn_ctxt
|
||||||
|
@ -367,12 +367,12 @@ type block_ctxt = {
|
||||||
|
|
||||||
// FIXME: we should be able to use option<@block_parent> here but
|
// FIXME: we should be able to use option<@block_parent> here but
|
||||||
// the infinite-enum check in rustboot gets upset.
|
// the infinite-enum check in rustboot gets upset.
|
||||||
enum block_parent { parent_none, parent_some(@block_ctxt), }
|
enum block_parent { parent_none, parent_some(block), }
|
||||||
|
|
||||||
type result = {bcx: @block_ctxt, val: ValueRef};
|
type result = {bcx: block, val: ValueRef};
|
||||||
type result_t = {bcx: @block_ctxt, val: ValueRef, ty: ty::t};
|
type result_t = {bcx: block, val: ValueRef, ty: ty::t};
|
||||||
|
|
||||||
fn rslt(bcx: @block_ctxt, val: ValueRef) -> result {
|
fn rslt(bcx: block, val: ValueRef) -> result {
|
||||||
{bcx: bcx, val: val}
|
{bcx: bcx, val: val}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -393,23 +393,27 @@ fn struct_elt(llstructty: TypeRef, n: uint) -> TypeRef unsafe {
|
||||||
ret llvm::LLVMGetElementType(elt_tys[n]);
|
ret llvm::LLVMGetElementType(elt_tys[n]);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn in_scope_cx(cx: @block_ctxt, f: fn(scope_info)) {
|
fn in_scope_cx(cx: block, f: fn(scope_info)) {
|
||||||
let cur = cx;
|
let cur = cx;
|
||||||
while true {
|
while true {
|
||||||
alt cur.kind {
|
alt cur.kind {
|
||||||
scope_block(info) { f(info); ret; }
|
block_scope(info) { f(info); ret; }
|
||||||
_ {}
|
_ {}
|
||||||
}
|
}
|
||||||
cur = alt check cur.parent { parent_some(b) { b } };
|
cur = block_parent(cur);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn block_parent(cx: block) -> block {
|
||||||
|
alt check cx.parent { parent_some(b) { b } }
|
||||||
|
}
|
||||||
|
|
||||||
// Accessors
|
// Accessors
|
||||||
// TODO: When we have overloading, simplify these names!
|
// TODO: When we have overloading, simplify these names!
|
||||||
|
|
||||||
pure fn bcx_tcx(bcx: @block_ctxt) -> ty::ctxt { ret bcx.fcx.ccx.tcx; }
|
pure fn bcx_tcx(bcx: block) -> ty::ctxt { ret bcx.fcx.ccx.tcx; }
|
||||||
pure fn bcx_ccx(bcx: @block_ctxt) -> @crate_ctxt { ret bcx.fcx.ccx; }
|
pure fn bcx_ccx(bcx: block) -> @crate_ctxt { ret bcx.fcx.ccx; }
|
||||||
pure fn bcx_fcx(bcx: @block_ctxt) -> @fn_ctxt { ret bcx.fcx; }
|
pure fn bcx_fcx(bcx: block) -> @fn_ctxt { ret bcx.fcx; }
|
||||||
pure fn fcx_ccx(fcx: @fn_ctxt) -> @crate_ctxt { ret fcx.ccx; }
|
pure fn fcx_ccx(fcx: @fn_ctxt) -> @crate_ctxt { ret fcx.ccx; }
|
||||||
pure fn fcx_tcx(fcx: @fn_ctxt) -> ty::ctxt { ret fcx.ccx.tcx; }
|
pure fn fcx_tcx(fcx: @fn_ctxt) -> ty::ctxt { ret fcx.ccx.tcx; }
|
||||||
pure fn ccx_tcx(ccx: @crate_ctxt) -> ty::ctxt { ret ccx.tcx; }
|
pure fn ccx_tcx(ccx: @crate_ctxt) -> ty::ctxt { ret ccx.tcx; }
|
||||||
|
@ -838,7 +842,7 @@ fn C_shape(ccx: @crate_ctxt, bytes: [u8]) -> ValueRef {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
pure fn valid_variant_index(ix: uint, cx: @block_ctxt, enum_id: ast::def_id,
|
pure fn valid_variant_index(ix: uint, cx: block, enum_id: ast::def_id,
|
||||||
variant_id: ast::def_id) -> bool {
|
variant_id: ast::def_id) -> bool {
|
||||||
|
|
||||||
// Handwaving: it's ok to pretend this code is referentially
|
// Handwaving: it's ok to pretend this code is referentially
|
||||||
|
@ -882,17 +886,17 @@ fn hash_mono_id(&&mi: mono_id) -> uint {
|
||||||
h
|
h
|
||||||
}
|
}
|
||||||
|
|
||||||
fn umax(cx: @block_ctxt, a: ValueRef, b: ValueRef) -> ValueRef {
|
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);
|
||||||
ret build::Select(cx, cond, b, a);
|
ret build::Select(cx, cond, b, a);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn umin(cx: @block_ctxt, a: ValueRef, b: ValueRef) -> ValueRef {
|
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);
|
||||||
ret build::Select(cx, cond, a, b);
|
ret build::Select(cx, cond, a, b);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn align_to(cx: @block_ctxt, off: ValueRef, align: ValueRef) -> ValueRef {
|
fn align_to(cx: block, off: ValueRef, align: ValueRef) -> ValueRef {
|
||||||
let mask = build::Sub(cx, align, C_int(bcx_ccx(cx), 1));
|
let mask = build::Sub(cx, align, C_int(bcx_ccx(cx), 1));
|
||||||
let bumped = build::Add(cx, off, mask);
|
let bumped = build::Add(cx, off, mask);
|
||||||
ret build::And(cx, bumped, build::Not(cx, mask));
|
ret build::And(cx, bumped, build::Not(cx, mask));
|
||||||
|
@ -910,7 +914,7 @@ fn path_str(p: path) -> str {
|
||||||
r
|
r
|
||||||
}
|
}
|
||||||
|
|
||||||
fn node_id_type(bcx: @block_ctxt, id: ast::node_id) -> ty::t {
|
fn node_id_type(bcx: block, id: ast::node_id) -> ty::t {
|
||||||
let tcx = bcx_tcx(bcx);
|
let tcx = bcx_tcx(bcx);
|
||||||
let t = ty::node_id_to_type(tcx, id);
|
let t = ty::node_id_to_type(tcx, id);
|
||||||
alt bcx.fcx.param_substs {
|
alt bcx.fcx.param_substs {
|
||||||
|
@ -918,10 +922,10 @@ fn node_id_type(bcx: @block_ctxt, id: ast::node_id) -> ty::t {
|
||||||
_ { t }
|
_ { t }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn expr_ty(bcx: @block_ctxt, ex: @ast::expr) -> ty::t {
|
fn expr_ty(bcx: block, ex: @ast::expr) -> ty::t {
|
||||||
node_id_type(bcx, ex.id)
|
node_id_type(bcx, ex.id)
|
||||||
}
|
}
|
||||||
fn node_id_type_params(bcx: @block_ctxt, id: ast::node_id) -> [ty::t] {
|
fn node_id_type_params(bcx: block, id: ast::node_id) -> [ty::t] {
|
||||||
let tcx = bcx_tcx(bcx);
|
let tcx = bcx_tcx(bcx);
|
||||||
let params = ty::node_id_to_type_params(tcx, id);
|
let params = ty::node_id_to_type_params(tcx, id);
|
||||||
alt bcx.fcx.param_substs {
|
alt bcx.fcx.param_substs {
|
||||||
|
|
|
@ -59,14 +59,14 @@ fn trans_impl(ccx: @crate_ctxt, path: path, name: ast::ident,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn trans_self_arg(bcx: @block_ctxt, base: @ast::expr) -> result {
|
fn trans_self_arg(bcx: block, base: @ast::expr) -> result {
|
||||||
let basety = expr_ty(bcx, base);
|
let basety = expr_ty(bcx, base);
|
||||||
let m_by_ref = ast::expl(ast::by_ref);
|
let m_by_ref = ast::expl(ast::by_ref);
|
||||||
trans_arg_expr(bcx, {mode: m_by_ref, ty: basety},
|
trans_arg_expr(bcx, {mode: m_by_ref, ty: basety},
|
||||||
T_ptr(type_of_or_i8(bcx_ccx(bcx), basety)), base)
|
T_ptr(type_of_or_i8(bcx_ccx(bcx), basety)), base)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn trans_method_callee(bcx: @block_ctxt, callee_id: ast::node_id,
|
fn trans_method_callee(bcx: block, callee_id: ast::node_id,
|
||||||
self: @ast::expr, origin: typeck::method_origin)
|
self: @ast::expr, origin: typeck::method_origin)
|
||||||
-> lval_maybe_callee {
|
-> lval_maybe_callee {
|
||||||
alt origin {
|
alt origin {
|
||||||
|
@ -91,7 +91,7 @@ fn trans_method_callee(bcx: @block_ctxt, callee_id: ast::node_id,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Method callee where the method is statically known
|
// Method callee where the method is statically known
|
||||||
fn trans_static_callee(bcx: @block_ctxt, callee_id: ast::node_id,
|
fn trans_static_callee(bcx: block, callee_id: ast::node_id,
|
||||||
base: @ast::expr, did: ast::def_id,
|
base: @ast::expr, did: ast::def_id,
|
||||||
substs: option<([ty::t], typeck::dict_res)>)
|
substs: option<([ty::t], typeck::dict_res)>)
|
||||||
-> lval_maybe_callee {
|
-> lval_maybe_callee {
|
||||||
|
@ -107,7 +107,7 @@ fn wrapper_fn_ty(ccx: @crate_ctxt, dict_ty: TypeRef, fty: ty::t,
|
||||||
{ty: fty, llty: T_fn([dict_ty] + inputs, output)}
|
{ty: fty, llty: T_fn([dict_ty] + inputs, output)}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn trans_vtable_callee(bcx: @block_ctxt, env: callee_env, dict: ValueRef,
|
fn trans_vtable_callee(bcx: block, env: callee_env, dict: ValueRef,
|
||||||
callee_id: ast::node_id, iface_id: ast::def_id,
|
callee_id: ast::node_id, iface_id: ast::def_id,
|
||||||
n_method: uint) -> lval_maybe_callee {
|
n_method: uint) -> lval_maybe_callee {
|
||||||
let bcx = bcx, ccx = bcx_ccx(bcx), tcx = ccx.tcx;
|
let bcx = bcx, ccx = bcx_ccx(bcx), tcx = ccx.tcx;
|
||||||
|
@ -140,7 +140,7 @@ fn trans_vtable_callee(bcx: @block_ctxt, env: callee_env, dict: ValueRef,
|
||||||
generic: generic}
|
generic: generic}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn trans_monomorphized_callee(bcx: @block_ctxt, callee_id: ast::node_id,
|
fn trans_monomorphized_callee(bcx: block, callee_id: ast::node_id,
|
||||||
base: @ast::expr, iface_id: ast::def_id,
|
base: @ast::expr, iface_id: ast::def_id,
|
||||||
n_method: uint, n_param: uint, n_bound: uint,
|
n_method: uint, n_param: uint, n_bound: uint,
|
||||||
substs: param_substs) -> lval_maybe_callee {
|
substs: param_substs) -> lval_maybe_callee {
|
||||||
|
@ -172,7 +172,7 @@ fn trans_monomorphized_callee(bcx: @block_ctxt, callee_id: ast::node_id,
|
||||||
|
|
||||||
|
|
||||||
// Method callee where the dict comes from a type param
|
// Method callee where the dict comes from a type param
|
||||||
fn trans_param_callee(bcx: @block_ctxt, callee_id: ast::node_id,
|
fn trans_param_callee(bcx: block, callee_id: ast::node_id,
|
||||||
base: @ast::expr, iface_id: ast::def_id, n_method: uint,
|
base: @ast::expr, iface_id: ast::def_id, n_method: uint,
|
||||||
n_param: uint, n_bound: uint) -> lval_maybe_callee {
|
n_param: uint, n_bound: uint) -> lval_maybe_callee {
|
||||||
let {bcx, val} = trans_self_arg(bcx, base);
|
let {bcx, val} = trans_self_arg(bcx, base);
|
||||||
|
@ -182,7 +182,7 @@ fn trans_param_callee(bcx: @block_ctxt, callee_id: ast::node_id,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Method callee where the dict comes from a boxed iface
|
// Method callee where the dict comes from a boxed iface
|
||||||
fn trans_iface_callee(bcx: @block_ctxt, callee_id: ast::node_id,
|
fn trans_iface_callee(bcx: block, callee_id: ast::node_id,
|
||||||
base: @ast::expr, iface_id: ast::def_id, n_method: uint)
|
base: @ast::expr, iface_id: ast::def_id, n_method: uint)
|
||||||
-> lval_maybe_callee {
|
-> lval_maybe_callee {
|
||||||
let {bcx, val} = trans_temp_expr(bcx, base);
|
let {bcx, val} = trans_temp_expr(bcx, base);
|
||||||
|
@ -266,12 +266,12 @@ fn resolve_dicts_in_fn_ctxt(fcx: @fn_ctxt, dicts: typeck::dict_res)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn trans_wrapper(ccx: @crate_ctxt, pt: path, llfty: TypeRef,
|
fn trans_wrapper(ccx: @crate_ctxt, pt: path, llfty: TypeRef,
|
||||||
fill: fn(ValueRef, @block_ctxt) -> @block_ctxt)
|
fill: fn(ValueRef, block) -> block)
|
||||||
-> ValueRef {
|
-> ValueRef {
|
||||||
let name = link::mangle_internal_name_by_path(ccx, pt);
|
let name = link::mangle_internal_name_by_path(ccx, pt);
|
||||||
let llfn = decl_internal_cdecl_fn(ccx.llmod, name, llfty);
|
let llfn = decl_internal_cdecl_fn(ccx.llmod, name, llfty);
|
||||||
let fcx = new_fn_ctxt(ccx, [], llfn, none);
|
let fcx = new_fn_ctxt(ccx, [], llfn, none);
|
||||||
let bcx = new_top_block_ctxt(fcx, none), lltop = bcx.llbb;
|
let bcx = top_scope_block(fcx, none), lltop = bcx.llbb;
|
||||||
let bcx = fill(llfn, bcx);
|
let bcx = fill(llfn, bcx);
|
||||||
build_return(bcx);
|
build_return(bcx);
|
||||||
finish_fn(fcx, lltop);
|
finish_fn(fcx, lltop);
|
||||||
|
@ -396,7 +396,7 @@ fn dict_is_static(tcx: ty::ctxt, origin: typeck::dict_origin) -> bool {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_dict(bcx: @block_ctxt, origin: typeck::dict_origin) -> result {
|
fn get_dict(bcx: block, origin: typeck::dict_origin) -> result {
|
||||||
let ccx = bcx_ccx(bcx);
|
let ccx = bcx_ccx(bcx);
|
||||||
alt origin {
|
alt origin {
|
||||||
typeck::dict_static(impl_did, tys, sub_origins) {
|
typeck::dict_static(impl_did, tys, sub_origins) {
|
||||||
|
@ -453,7 +453,7 @@ fn dict_id(tcx: ty::ctxt, origin: typeck::dict_origin) -> dict_id {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_static_dict(bcx: @block_ctxt, origin: typeck::dict_origin)
|
fn get_static_dict(bcx: block, origin: typeck::dict_origin)
|
||||||
-> ValueRef {
|
-> ValueRef {
|
||||||
let ccx = bcx_ccx(bcx);
|
let ccx = bcx_ccx(bcx);
|
||||||
let id = dict_id(ccx.tcx, origin);
|
let id = dict_id(ccx.tcx, origin);
|
||||||
|
@ -474,8 +474,8 @@ fn get_static_dict(bcx: @block_ctxt, origin: typeck::dict_origin)
|
||||||
cast
|
cast
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_dict_ptrs(bcx: @block_ctxt, origin: typeck::dict_origin)
|
fn get_dict_ptrs(bcx: block, origin: typeck::dict_origin)
|
||||||
-> {bcx: @block_ctxt, ptrs: [ValueRef]} {
|
-> {bcx: block, ptrs: [ValueRef]} {
|
||||||
let ccx = bcx_ccx(bcx);
|
let ccx = bcx_ccx(bcx);
|
||||||
fn get_vtable(ccx: @crate_ctxt, did: ast::def_id) -> ValueRef {
|
fn get_vtable(ccx: @crate_ctxt, did: ast::def_id) -> ValueRef {
|
||||||
if did.crate == ast::local_crate {
|
if did.crate == ast::local_crate {
|
||||||
|
@ -517,8 +517,8 @@ fn get_dict_ptrs(bcx: @block_ctxt, origin: typeck::dict_origin)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn trans_cast(bcx: @block_ctxt, val: @ast::expr, id: ast::node_id, dest: dest)
|
fn trans_cast(bcx: block, val: @ast::expr, id: ast::node_id, dest: dest)
|
||||||
-> @block_ctxt {
|
-> block {
|
||||||
if dest == ignore { ret trans_expr(bcx, val, ignore); }
|
if dest == ignore { ret trans_expr(bcx, val, ignore); }
|
||||||
let ccx = bcx_ccx(bcx);
|
let ccx = bcx_ccx(bcx);
|
||||||
let v_ty = expr_ty(bcx, val);
|
let v_ty = expr_ty(bcx, val);
|
||||||
|
|
|
@ -54,10 +54,10 @@ fn c_stack_tys(ccx: @crate_ctxt,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
type shim_arg_builder = fn(bcx: @block_ctxt, tys: @c_stack_tys,
|
type shim_arg_builder = fn(bcx: block, tys: @c_stack_tys,
|
||||||
llargbundle: ValueRef) -> [ValueRef];
|
llargbundle: ValueRef) -> [ValueRef];
|
||||||
|
|
||||||
type shim_ret_builder = fn(bcx: @block_ctxt, tys: @c_stack_tys,
|
type shim_ret_builder = fn(bcx: block, tys: @c_stack_tys,
|
||||||
llargbundle: ValueRef, llretval: ValueRef);
|
llargbundle: ValueRef, llretval: ValueRef);
|
||||||
|
|
||||||
fn build_shim_fn_(ccx: @crate_ctxt,
|
fn build_shim_fn_(ccx: @crate_ctxt,
|
||||||
|
@ -73,7 +73,7 @@ fn build_shim_fn_(ccx: @crate_ctxt,
|
||||||
|
|
||||||
// Declare the body of the shim function:
|
// Declare the body of the shim function:
|
||||||
let fcx = new_fn_ctxt(ccx, [], llshimfn, none);
|
let fcx = new_fn_ctxt(ccx, [], llshimfn, none);
|
||||||
let bcx = new_top_block_ctxt(fcx, none);
|
let bcx = top_scope_block(fcx, none);
|
||||||
let lltop = bcx.llbb;
|
let lltop = bcx.llbb;
|
||||||
let llargbundle = llvm::LLVMGetParam(llshimfn, 0 as c_uint);
|
let llargbundle = llvm::LLVMGetParam(llshimfn, 0 as c_uint);
|
||||||
let llargvals = arg_builder(bcx, tys, llargbundle);
|
let llargvals = arg_builder(bcx, tys, llargbundle);
|
||||||
|
@ -90,11 +90,11 @@ fn build_shim_fn_(ccx: @crate_ctxt,
|
||||||
ret llshimfn;
|
ret llshimfn;
|
||||||
}
|
}
|
||||||
|
|
||||||
type wrap_arg_builder = fn(bcx: @block_ctxt, tys: @c_stack_tys,
|
type wrap_arg_builder = fn(bcx: block, tys: @c_stack_tys,
|
||||||
llwrapfn: ValueRef,
|
llwrapfn: ValueRef,
|
||||||
llargbundle: ValueRef);
|
llargbundle: ValueRef);
|
||||||
|
|
||||||
type wrap_ret_builder = fn(bcx: @block_ctxt, tys: @c_stack_tys,
|
type wrap_ret_builder = fn(bcx: block, tys: @c_stack_tys,
|
||||||
llargbundle: ValueRef);
|
llargbundle: ValueRef);
|
||||||
|
|
||||||
fn build_wrap_fn_(ccx: @crate_ctxt,
|
fn build_wrap_fn_(ccx: @crate_ctxt,
|
||||||
|
@ -106,7 +106,7 @@ fn build_wrap_fn_(ccx: @crate_ctxt,
|
||||||
ret_builder: wrap_ret_builder) {
|
ret_builder: wrap_ret_builder) {
|
||||||
|
|
||||||
let fcx = new_fn_ctxt(ccx, [], llwrapfn, none);
|
let fcx = new_fn_ctxt(ccx, [], llwrapfn, none);
|
||||||
let bcx = new_top_block_ctxt(fcx, none);
|
let bcx = top_scope_block(fcx, none);
|
||||||
let lltop = bcx.llbb;
|
let lltop = bcx.llbb;
|
||||||
|
|
||||||
// Allocate the struct and write the arguments into it.
|
// Allocate the struct and write the arguments into it.
|
||||||
|
@ -122,7 +122,7 @@ fn build_wrap_fn_(ccx: @crate_ctxt,
|
||||||
tie_up_header_blocks(fcx, lltop);
|
tie_up_header_blocks(fcx, lltop);
|
||||||
|
|
||||||
// Make sure our standard return block (that we didn't use) is terminated
|
// Make sure our standard return block (that we didn't use) is terminated
|
||||||
let ret_cx = new_raw_block_ctxt(fcx, fcx.llreturn);
|
let ret_cx = raw_block(fcx, fcx.llreturn);
|
||||||
Unreachable(ret_cx);
|
Unreachable(ret_cx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -168,7 +168,7 @@ fn trans_native_mod(ccx: @crate_ctxt,
|
||||||
tys: @c_stack_tys,
|
tys: @c_stack_tys,
|
||||||
cc: lib::llvm::CallConv) -> ValueRef {
|
cc: lib::llvm::CallConv) -> ValueRef {
|
||||||
|
|
||||||
fn build_args(bcx: @block_ctxt, tys: @c_stack_tys,
|
fn build_args(bcx: block, tys: @c_stack_tys,
|
||||||
llargbundle: ValueRef) -> [ValueRef] {
|
llargbundle: ValueRef) -> [ValueRef] {
|
||||||
let llargvals = [];
|
let llargvals = [];
|
||||||
let i = 0u;
|
let i = 0u;
|
||||||
|
@ -181,7 +181,7 @@ fn trans_native_mod(ccx: @crate_ctxt,
|
||||||
ret llargvals;
|
ret llargvals;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn build_ret(bcx: @block_ctxt, tys: @c_stack_tys,
|
fn build_ret(bcx: block, tys: @c_stack_tys,
|
||||||
llargbundle: ValueRef, llretval: ValueRef) {
|
llargbundle: ValueRef, llretval: ValueRef) {
|
||||||
if tys.ret_def {
|
if tys.ret_def {
|
||||||
let n = vec::len(tys.arg_tys);
|
let n = vec::len(tys.arg_tys);
|
||||||
|
@ -210,7 +210,7 @@ fn trans_native_mod(ccx: @crate_ctxt,
|
||||||
llshimfn: ValueRef,
|
llshimfn: ValueRef,
|
||||||
llwrapfn: ValueRef) {
|
llwrapfn: ValueRef) {
|
||||||
|
|
||||||
fn build_args(bcx: @block_ctxt, tys: @c_stack_tys,
|
fn build_args(bcx: block, tys: @c_stack_tys,
|
||||||
llwrapfn: ValueRef, llargbundle: ValueRef,
|
llwrapfn: ValueRef, llargbundle: ValueRef,
|
||||||
num_tps: uint) {
|
num_tps: uint) {
|
||||||
let i = 0u, n = vec::len(tys.arg_tys);
|
let i = 0u, n = vec::len(tys.arg_tys);
|
||||||
|
@ -226,7 +226,7 @@ fn trans_native_mod(ccx: @crate_ctxt,
|
||||||
store_inbounds(bcx, llretptr, llargbundle, [0, n as int]);
|
store_inbounds(bcx, llretptr, llargbundle, [0, n as int]);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn build_ret(bcx: @block_ctxt, _tys: @c_stack_tys,
|
fn build_ret(bcx: block, _tys: @c_stack_tys,
|
||||||
_llargbundle: ValueRef) {
|
_llargbundle: ValueRef) {
|
||||||
RetVoid(bcx);
|
RetVoid(bcx);
|
||||||
}
|
}
|
||||||
|
@ -283,7 +283,7 @@ fn trans_crust_fn(ccx: @crate_ctxt, path: ast_map::path, decl: ast::fn_decl,
|
||||||
fn build_shim_fn(ccx: @crate_ctxt, path: ast_map::path,
|
fn build_shim_fn(ccx: @crate_ctxt, path: ast_map::path,
|
||||||
llrustfn: ValueRef, tys: @c_stack_tys) -> ValueRef {
|
llrustfn: ValueRef, tys: @c_stack_tys) -> ValueRef {
|
||||||
|
|
||||||
fn build_args(bcx: @block_ctxt, tys: @c_stack_tys,
|
fn build_args(bcx: block, tys: @c_stack_tys,
|
||||||
llargbundle: ValueRef) -> [ValueRef] {
|
llargbundle: ValueRef) -> [ValueRef] {
|
||||||
let llargvals = [];
|
let llargvals = [];
|
||||||
let i = 0u;
|
let i = 0u;
|
||||||
|
@ -300,7 +300,7 @@ fn trans_crust_fn(ccx: @crate_ctxt, path: ast_map::path, decl: ast::fn_decl,
|
||||||
ret llargvals;
|
ret llargvals;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn build_ret(_bcx: @block_ctxt, _tys: @c_stack_tys,
|
fn build_ret(_bcx: block, _tys: @c_stack_tys,
|
||||||
_llargbundle: ValueRef, _llretval: ValueRef) {
|
_llargbundle: ValueRef, _llretval: ValueRef) {
|
||||||
// Nop. The return pointer in the Rust ABI function
|
// Nop. The return pointer in the Rust ABI function
|
||||||
// is wired directly into the return slot in the shim struct
|
// is wired directly into the return slot in the shim struct
|
||||||
|
@ -316,7 +316,7 @@ fn trans_crust_fn(ccx: @crate_ctxt, path: ast_map::path, decl: ast::fn_decl,
|
||||||
fn build_wrap_fn(ccx: @crate_ctxt, llshimfn: ValueRef,
|
fn build_wrap_fn(ccx: @crate_ctxt, llshimfn: ValueRef,
|
||||||
llwrapfn: ValueRef, tys: @c_stack_tys) {
|
llwrapfn: ValueRef, tys: @c_stack_tys) {
|
||||||
|
|
||||||
fn build_args(bcx: @block_ctxt, tys: @c_stack_tys,
|
fn build_args(bcx: block, tys: @c_stack_tys,
|
||||||
llwrapfn: ValueRef, llargbundle: ValueRef) {
|
llwrapfn: ValueRef, llargbundle: ValueRef) {
|
||||||
let llretptr = alloca(bcx, tys.ret_ty);
|
let llretptr = alloca(bcx, tys.ret_ty);
|
||||||
let i = 0u, n = vec::len(tys.arg_tys);
|
let i = 0u, n = vec::len(tys.arg_tys);
|
||||||
|
@ -329,7 +329,7 @@ fn trans_crust_fn(ccx: @crate_ctxt, path: ast_map::path, decl: ast::fn_decl,
|
||||||
store_inbounds(bcx, llretptr, llargbundle, [0, n as int]);
|
store_inbounds(bcx, llretptr, llargbundle, [0, n as int]);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn build_ret(bcx: @block_ctxt, tys: @c_stack_tys,
|
fn build_ret(bcx: block, tys: @c_stack_tys,
|
||||||
llargbundle: ValueRef) {
|
llargbundle: ValueRef) {
|
||||||
let n = vec::len(tys.arg_tys);
|
let n = vec::len(tys.arg_tys);
|
||||||
let llretval = load_inbounds(bcx, llargbundle, [0, n as int]);
|
let llretval = load_inbounds(bcx, llargbundle, [0, n as int]);
|
||||||
|
|
|
@ -8,7 +8,7 @@ import driver::session::session;
|
||||||
import trans::base;
|
import trans::base;
|
||||||
import middle::trans::common::{crate_ctxt, val_ty, C_bytes, C_int,
|
import middle::trans::common::{crate_ctxt, val_ty, C_bytes, C_int,
|
||||||
C_named_struct, C_struct, T_enum_variant,
|
C_named_struct, C_struct, T_enum_variant,
|
||||||
block_ctxt, result, rslt, bcx_ccx, bcx_tcx,
|
block, result, rslt, bcx_ccx, bcx_tcx,
|
||||||
type_has_static_size, umax, umin, align_to,
|
type_has_static_size, umax, umin, align_to,
|
||||||
tydesc_info};
|
tydesc_info};
|
||||||
import back::abi;
|
import back::abi;
|
||||||
|
@ -593,19 +593,19 @@ fn gen_shape_tables(ccx: @crate_ctxt) {
|
||||||
// compute sizeof / alignof
|
// compute sizeof / alignof
|
||||||
|
|
||||||
type metrics = {
|
type metrics = {
|
||||||
bcx: @block_ctxt,
|
bcx: block,
|
||||||
sz: ValueRef,
|
sz: ValueRef,
|
||||||
align: ValueRef
|
align: ValueRef
|
||||||
};
|
};
|
||||||
|
|
||||||
type tag_metrics = {
|
type tag_metrics = {
|
||||||
bcx: @block_ctxt,
|
bcx: block,
|
||||||
sz: ValueRef,
|
sz: ValueRef,
|
||||||
align: ValueRef,
|
align: ValueRef,
|
||||||
payload_align: ValueRef
|
payload_align: ValueRef
|
||||||
};
|
};
|
||||||
|
|
||||||
fn size_of(bcx: @block_ctxt, t: ty::t) -> result {
|
fn size_of(bcx: block, t: ty::t) -> result {
|
||||||
let ccx = bcx_ccx(bcx);
|
let ccx = bcx_ccx(bcx);
|
||||||
if check type_has_static_size(ccx, t) {
|
if check type_has_static_size(ccx, t) {
|
||||||
rslt(bcx, llsize_of(ccx, base::type_of(ccx, t)))
|
rslt(bcx, llsize_of(ccx, base::type_of(ccx, t)))
|
||||||
|
@ -615,7 +615,7 @@ fn size_of(bcx: @block_ctxt, t: ty::t) -> result {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn align_of(bcx: @block_ctxt, t: ty::t) -> result {
|
fn align_of(bcx: block, t: ty::t) -> result {
|
||||||
let ccx = bcx_ccx(bcx);
|
let ccx = bcx_ccx(bcx);
|
||||||
if check type_has_static_size(ccx, t) {
|
if check type_has_static_size(ccx, t) {
|
||||||
rslt(bcx, llalign_of(ccx, base::type_of(ccx, t)))
|
rslt(bcx, llalign_of(ccx, base::type_of(ccx, t)))
|
||||||
|
@ -625,7 +625,7 @@ fn align_of(bcx: @block_ctxt, t: ty::t) -> result {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn metrics(bcx: @block_ctxt, t: ty::t) -> metrics {
|
fn metrics(bcx: block, t: ty::t) -> metrics {
|
||||||
let ccx = bcx_ccx(bcx);
|
let ccx = bcx_ccx(bcx);
|
||||||
if check type_has_static_size(ccx, t) {
|
if check type_has_static_size(ccx, t) {
|
||||||
let llty = base::type_of(ccx, t);
|
let llty = base::type_of(ccx, t);
|
||||||
|
@ -688,8 +688,8 @@ fn static_size_of_enum(cx: @crate_ctxt, t: ty::t)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn dynamic_metrics(cx: @block_ctxt, t: ty::t) -> metrics {
|
fn dynamic_metrics(cx: block, t: ty::t) -> metrics {
|
||||||
fn align_elements(cx: @block_ctxt, elts: [ty::t]) -> metrics {
|
fn align_elements(cx: block, elts: [ty::t]) -> metrics {
|
||||||
//
|
//
|
||||||
// C padding rules:
|
// C padding rules:
|
||||||
//
|
//
|
||||||
|
@ -736,7 +736,7 @@ fn dynamic_metrics(cx: @block_ctxt, t: ty::t) -> metrics {
|
||||||
let bcx = cx;
|
let bcx = cx;
|
||||||
let ccx = bcx_ccx(bcx);
|
let ccx = bcx_ccx(bcx);
|
||||||
|
|
||||||
let compute_max_variant_size = fn@(bcx: @block_ctxt) -> result {
|
let compute_max_variant_size = fn@(bcx: block) -> result {
|
||||||
// Compute max(variant sizes).
|
// Compute max(variant sizes).
|
||||||
let bcx = bcx;
|
let bcx = bcx;
|
||||||
let max_size: ValueRef = C_int(ccx, 0);
|
let max_size: ValueRef = C_int(ccx, 0);
|
||||||
|
@ -799,7 +799,7 @@ fn simplify_type(tcx: ty::ctxt, typ: ty::t) -> ty::t {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Given a tag type `ty`, returns the offset of the payload.
|
// Given a tag type `ty`, returns the offset of the payload.
|
||||||
//fn tag_payload_offs(bcx: @block_ctxt, tag_id: ast::def_id, tps: [ty::t])
|
//fn tag_payload_offs(bcx: block, tag_id: ast::def_id, tps: [ty::t])
|
||||||
// -> ValueRef {
|
// -> ValueRef {
|
||||||
// alt tag_kind(tag_id) {
|
// alt tag_kind(tag_id) {
|
||||||
// tk_unit | tk_enum | tk_newtype { C_int(bcx_ccx(bcx), 0) }
|
// tk_unit | tk_enum | tk_newtype { C_int(bcx_ccx(bcx), 0) }
|
||||||
|
|
|
@ -4,28 +4,28 @@ import lib::llvm::{ValueRef, TypeRef};
|
||||||
import back::abi;
|
import back::abi;
|
||||||
import base::{call_memmove, trans_shared_malloc, type_of_or_i8,
|
import base::{call_memmove, trans_shared_malloc, type_of_or_i8,
|
||||||
INIT, copy_val, load_if_immediate, get_tydesc,
|
INIT, copy_val, load_if_immediate, get_tydesc,
|
||||||
new_sub_block_ctxt, do_spill_noroot,
|
sub_block, do_spill_noroot,
|
||||||
dest};
|
dest};
|
||||||
import shape::{llsize_of, size_of};
|
import shape::{llsize_of, size_of};
|
||||||
import build::*;
|
import build::*;
|
||||||
import common::*;
|
import common::*;
|
||||||
|
|
||||||
fn get_fill(bcx: @block_ctxt, vptr: ValueRef) -> ValueRef {
|
fn get_fill(bcx: block, vptr: ValueRef) -> ValueRef {
|
||||||
Load(bcx, GEPi(bcx, vptr, [0, abi::vec_elt_fill]))
|
Load(bcx, GEPi(bcx, vptr, [0, abi::vec_elt_fill]))
|
||||||
}
|
}
|
||||||
fn get_dataptr(bcx: @block_ctxt, vptr: ValueRef, unit_ty: TypeRef)
|
fn get_dataptr(bcx: block, vptr: ValueRef, unit_ty: TypeRef)
|
||||||
-> ValueRef {
|
-> ValueRef {
|
||||||
let ptr = GEPi(bcx, vptr, [0, abi::vec_elt_elems]);
|
let ptr = GEPi(bcx, vptr, [0, abi::vec_elt_elems]);
|
||||||
PointerCast(bcx, ptr, T_ptr(unit_ty))
|
PointerCast(bcx, ptr, T_ptr(unit_ty))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pointer_add(bcx: @block_ctxt, ptr: ValueRef, bytes: ValueRef) -> ValueRef {
|
fn pointer_add(bcx: block, ptr: ValueRef, bytes: ValueRef) -> ValueRef {
|
||||||
let old_ty = val_ty(ptr);
|
let old_ty = val_ty(ptr);
|
||||||
let bptr = PointerCast(bcx, ptr, T_ptr(T_i8()));
|
let bptr = PointerCast(bcx, ptr, T_ptr(T_i8()));
|
||||||
ret PointerCast(bcx, InBoundsGEP(bcx, bptr, [bytes]), old_ty);
|
ret PointerCast(bcx, InBoundsGEP(bcx, bptr, [bytes]), old_ty);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn alloc_raw(bcx: @block_ctxt, fill: ValueRef, alloc: ValueRef) -> result {
|
fn alloc_raw(bcx: block, fill: ValueRef, alloc: ValueRef) -> result {
|
||||||
let ccx = bcx_ccx(bcx);
|
let ccx = bcx_ccx(bcx);
|
||||||
let llvecty = ccx.opaque_vec_type;
|
let llvecty = ccx.opaque_vec_type;
|
||||||
let vecsize = Add(bcx, alloc, llsize_of(ccx, llvecty));
|
let vecsize = Add(bcx, alloc, llsize_of(ccx, llvecty));
|
||||||
|
@ -37,13 +37,13 @@ fn alloc_raw(bcx: @block_ctxt, fill: ValueRef, alloc: ValueRef) -> result {
|
||||||
}
|
}
|
||||||
|
|
||||||
type alloc_result =
|
type alloc_result =
|
||||||
{bcx: @block_ctxt,
|
{bcx: block,
|
||||||
val: ValueRef,
|
val: ValueRef,
|
||||||
unit_ty: ty::t,
|
unit_ty: ty::t,
|
||||||
llunitsz: ValueRef,
|
llunitsz: ValueRef,
|
||||||
llunitty: TypeRef};
|
llunitty: TypeRef};
|
||||||
|
|
||||||
fn alloc(bcx: @block_ctxt, vec_ty: ty::t, elts: uint) -> alloc_result {
|
fn alloc(bcx: block, vec_ty: ty::t, elts: uint) -> alloc_result {
|
||||||
let ccx = bcx_ccx(bcx);
|
let ccx = bcx_ccx(bcx);
|
||||||
let unit_ty = ty::sequence_element_type(bcx_tcx(bcx), vec_ty);
|
let unit_ty = ty::sequence_element_type(bcx_tcx(bcx), vec_ty);
|
||||||
let llunitty = type_of_or_i8(ccx, unit_ty);
|
let llunitty = type_of_or_i8(ccx, unit_ty);
|
||||||
|
@ -66,7 +66,7 @@ fn alloc(bcx: @block_ctxt, vec_ty: ty::t, elts: uint) -> alloc_result {
|
||||||
llunitty: llunitty};
|
llunitty: llunitty};
|
||||||
}
|
}
|
||||||
|
|
||||||
fn duplicate(bcx: @block_ctxt, vptr: ValueRef, vec_ty: ty::t) -> result {
|
fn duplicate(bcx: block, vptr: ValueRef, vec_ty: ty::t) -> result {
|
||||||
let ccx = bcx_ccx(bcx);
|
let ccx = bcx_ccx(bcx);
|
||||||
let fill = get_fill(bcx, vptr);
|
let fill = get_fill(bcx, vptr);
|
||||||
let size = Add(bcx, fill, llsize_of(ccx, ccx.opaque_vec_type));
|
let size = Add(bcx, fill, llsize_of(ccx, ccx.opaque_vec_type));
|
||||||
|
@ -80,23 +80,19 @@ fn duplicate(bcx: @block_ctxt, vptr: ValueRef, vec_ty: ty::t) -> result {
|
||||||
}
|
}
|
||||||
ret rslt(bcx, newptr);
|
ret rslt(bcx, newptr);
|
||||||
}
|
}
|
||||||
fn make_free_glue(bcx: @block_ctxt, vptr: ValueRef, vec_ty: ty::t) ->
|
fn make_free_glue(bcx: block, vptr: ValueRef, vec_ty: ty::t) ->
|
||||||
@block_ctxt {
|
block {
|
||||||
let unit_ty = ty::sequence_element_type(bcx_tcx(bcx), vec_ty);
|
let tcx = bcx_tcx(bcx), unit_ty = ty::sequence_element_type(tcx, vec_ty);
|
||||||
let drop_cx = new_sub_block_ctxt(bcx, "drop");
|
base::with_cond(bcx, IsNotNull(bcx, vptr)) {|bcx|
|
||||||
let next_cx = new_sub_block_ctxt(bcx, "next");
|
let bcx = if ty::type_needs_drop(tcx, unit_ty) {
|
||||||
let null_test = IsNull(bcx, vptr);
|
iter_vec(bcx, vptr, vec_ty, base::drop_ty)
|
||||||
CondBr(bcx, null_test, next_cx.llbb, drop_cx.llbb);
|
} else { bcx };
|
||||||
if ty::type_needs_drop(bcx_tcx(bcx), unit_ty) {
|
base::trans_shared_free(bcx, vptr)
|
||||||
drop_cx = iter_vec(drop_cx, vptr, vec_ty, base::drop_ty);
|
|
||||||
}
|
}
|
||||||
drop_cx = base::trans_shared_free(drop_cx, vptr);
|
|
||||||
Br(drop_cx, next_cx.llbb);
|
|
||||||
ret next_cx;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn trans_vec(bcx: @block_ctxt, args: [@ast::expr], id: ast::node_id,
|
fn trans_vec(bcx: block, args: [@ast::expr], id: ast::node_id,
|
||||||
dest: dest) -> @block_ctxt {
|
dest: dest) -> block {
|
||||||
let ccx = bcx_ccx(bcx), bcx = bcx;
|
let ccx = bcx_ccx(bcx), bcx = bcx;
|
||||||
if dest == base::ignore {
|
if dest == base::ignore {
|
||||||
for arg in args {
|
for arg in args {
|
||||||
|
@ -129,7 +125,7 @@ fn trans_vec(bcx: @block_ctxt, args: [@ast::expr], id: ast::node_id,
|
||||||
ret base::store_in_dest(bcx, vptr, dest);
|
ret base::store_in_dest(bcx, vptr, dest);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn trans_str(bcx: @block_ctxt, s: str, dest: dest) -> @block_ctxt {
|
fn trans_str(bcx: block, s: str, dest: dest) -> block {
|
||||||
let veclen = str::len_bytes(s) + 1u; // +1 for \0
|
let veclen = str::len_bytes(s) + 1u; // +1 for \0
|
||||||
let {bcx: bcx, val: sptr, _} =
|
let {bcx: bcx, val: sptr, _} =
|
||||||
alloc(bcx, ty::mk_str(bcx_tcx(bcx)), veclen);
|
alloc(bcx, ty::mk_str(bcx_tcx(bcx)), veclen);
|
||||||
|
@ -142,8 +138,8 @@ fn trans_str(bcx: @block_ctxt, s: str, dest: dest) -> @block_ctxt {
|
||||||
ret base::store_in_dest(bcx, sptr, dest);
|
ret base::store_in_dest(bcx, sptr, dest);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn trans_append(cx: @block_ctxt, vec_ty: ty::t, lhsptr: ValueRef,
|
fn trans_append(cx: block, vec_ty: ty::t, lhsptr: ValueRef,
|
||||||
rhs: ValueRef) -> @block_ctxt {
|
rhs: ValueRef) -> block {
|
||||||
// Cast to opaque interior vector types if necessary.
|
// Cast to opaque interior vector types if necessary.
|
||||||
let ccx = bcx_ccx(cx);
|
let ccx = bcx_ccx(cx);
|
||||||
let unit_ty = ty::sequence_element_type(bcx_tcx(cx), vec_ty);
|
let unit_ty = ty::sequence_element_type(bcx_tcx(cx), vec_ty);
|
||||||
|
@ -206,8 +202,8 @@ fn trans_append(cx: @block_ctxt, vec_ty: ty::t, lhsptr: ValueRef,
|
||||||
ret bcx;
|
ret bcx;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn trans_append_literal(bcx: @block_ctxt, vptrptr: ValueRef, vec_ty: ty::t,
|
fn trans_append_literal(bcx: block, vptrptr: ValueRef, vec_ty: ty::t,
|
||||||
vals: [@ast::expr]) -> @block_ctxt {
|
vals: [@ast::expr]) -> block {
|
||||||
let ccx = bcx_ccx(bcx);
|
let ccx = bcx_ccx(bcx);
|
||||||
let elt_ty = ty::sequence_element_type(bcx_tcx(bcx), vec_ty);
|
let elt_ty = ty::sequence_element_type(bcx_tcx(bcx), vec_ty);
|
||||||
let ti = none;
|
let ti = none;
|
||||||
|
@ -227,8 +223,8 @@ fn trans_append_literal(bcx: @block_ctxt, vptrptr: ValueRef, vec_ty: ty::t,
|
||||||
ret bcx;
|
ret bcx;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn trans_add(bcx: @block_ctxt, vec_ty: ty::t, lhs: ValueRef,
|
fn trans_add(bcx: block, vec_ty: ty::t, lhs: ValueRef,
|
||||||
rhs: ValueRef, dest: dest) -> @block_ctxt {
|
rhs: ValueRef, dest: dest) -> block {
|
||||||
let ccx = bcx_ccx(bcx);
|
let ccx = bcx_ccx(bcx);
|
||||||
let strings = alt ty::get(vec_ty).struct {
|
let strings = alt ty::get(vec_ty).struct {
|
||||||
ty::ty_str { true }
|
ty::ty_str { true }
|
||||||
|
@ -247,8 +243,8 @@ fn trans_add(bcx: @block_ctxt, vec_ty: ty::t, lhs: ValueRef,
|
||||||
|
|
||||||
let write_ptr_ptr = do_spill_noroot
|
let write_ptr_ptr = do_spill_noroot
|
||||||
(bcx, get_dataptr(bcx, new_vec_ptr, llunitty));
|
(bcx, get_dataptr(bcx, new_vec_ptr, llunitty));
|
||||||
let copy_fn = fn@(bcx: @block_ctxt, addr: ValueRef,
|
let copy_fn = fn@(bcx: block, addr: ValueRef,
|
||||||
_ty: ty::t) -> @block_ctxt {
|
_ty: ty::t) -> block {
|
||||||
let ccx = bcx_ccx(bcx);
|
let ccx = bcx_ccx(bcx);
|
||||||
let write_ptr = Load(bcx, write_ptr_ptr);
|
let write_ptr = Load(bcx, write_ptr_ptr);
|
||||||
let bcx = copy_val(bcx, INIT, write_ptr,
|
let bcx = copy_val(bcx, INIT, write_ptr,
|
||||||
|
@ -269,12 +265,12 @@ fn trans_add(bcx: @block_ctxt, vec_ty: ty::t, lhs: ValueRef,
|
||||||
ret base::store_in_dest(bcx, new_vec_ptr, dest);
|
ret base::store_in_dest(bcx, new_vec_ptr, dest);
|
||||||
}
|
}
|
||||||
|
|
||||||
type val_and_ty_fn = fn@(@block_ctxt, ValueRef, ty::t) -> result;
|
type val_and_ty_fn = fn@(block, ValueRef, ty::t) -> result;
|
||||||
|
|
||||||
type iter_vec_block = fn(@block_ctxt, ValueRef, ty::t) -> @block_ctxt;
|
type iter_vec_block = fn(block, ValueRef, ty::t) -> block;
|
||||||
|
|
||||||
fn iter_vec_raw(bcx: @block_ctxt, vptr: ValueRef, vec_ty: ty::t,
|
fn iter_vec_raw(bcx: block, vptr: ValueRef, vec_ty: ty::t,
|
||||||
fill: ValueRef, f: iter_vec_block) -> @block_ctxt {
|
fill: ValueRef, f: iter_vec_block) -> block {
|
||||||
let ccx = bcx_ccx(bcx);
|
let ccx = bcx_ccx(bcx);
|
||||||
let unit_ty = ty::sequence_element_type(bcx_tcx(bcx), vec_ty);
|
let unit_ty = ty::sequence_element_type(bcx_tcx(bcx), vec_ty);
|
||||||
let llunitty = type_of_or_i8(ccx, unit_ty);
|
let llunitty = type_of_or_i8(ccx, unit_ty);
|
||||||
|
@ -288,13 +284,13 @@ fn iter_vec_raw(bcx: @block_ctxt, vptr: ValueRef, vec_ty: ty::t,
|
||||||
let data_end_ptr = pointer_add(bcx, data_ptr, fill);
|
let data_end_ptr = pointer_add(bcx, data_ptr, fill);
|
||||||
|
|
||||||
// Now perform the iteration.
|
// Now perform the iteration.
|
||||||
let header_cx = new_sub_block_ctxt(bcx, "iter_vec_loop_header");
|
let header_cx = sub_block(bcx, "iter_vec_loop_header");
|
||||||
Br(bcx, header_cx.llbb);
|
Br(bcx, header_cx.llbb);
|
||||||
let data_ptr = Phi(header_cx, val_ty(data_ptr), [data_ptr], [bcx.llbb]);
|
let data_ptr = Phi(header_cx, val_ty(data_ptr), [data_ptr], [bcx.llbb]);
|
||||||
let not_yet_at_end =
|
let not_yet_at_end =
|
||||||
ICmp(header_cx, lib::llvm::IntULT, data_ptr, data_end_ptr);
|
ICmp(header_cx, lib::llvm::IntULT, data_ptr, data_end_ptr);
|
||||||
let body_cx = new_sub_block_ctxt(header_cx, "iter_vec_loop_body");
|
let body_cx = sub_block(header_cx, "iter_vec_loop_body");
|
||||||
let next_cx = new_sub_block_ctxt(header_cx, "iter_vec_next");
|
let next_cx = sub_block(header_cx, "iter_vec_next");
|
||||||
CondBr(header_cx, not_yet_at_end, body_cx.llbb, next_cx.llbb);
|
CondBr(header_cx, not_yet_at_end, body_cx.llbb, next_cx.llbb);
|
||||||
body_cx = f(body_cx, data_ptr, unit_ty);
|
body_cx = f(body_cx, data_ptr, unit_ty);
|
||||||
let increment =
|
let increment =
|
||||||
|
@ -307,8 +303,8 @@ fn iter_vec_raw(bcx: @block_ctxt, vptr: ValueRef, vec_ty: ty::t,
|
||||||
ret next_cx;
|
ret next_cx;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn iter_vec(bcx: @block_ctxt, vptr: ValueRef, vec_ty: ty::t,
|
fn iter_vec(bcx: block, vptr: ValueRef, vec_ty: ty::t,
|
||||||
f: iter_vec_block) -> @block_ctxt {
|
f: iter_vec_block) -> block {
|
||||||
let ccx = bcx_ccx(bcx);
|
let ccx = bcx_ccx(bcx);
|
||||||
let vptr = PointerCast(bcx, vptr, T_ptr(ccx.opaque_vec_type));
|
let vptr = PointerCast(bcx, vptr, T_ptr(ccx.opaque_vec_type));
|
||||||
ret iter_vec_raw(bcx, vptr, vec_ty, get_fill(bcx, vptr), f);
|
ret iter_vec_raw(bcx, vptr, vec_ty, get_fill(bcx, vptr), f);
|
||||||
|
|
|
@ -2,31 +2,22 @@ import syntax::ast;
|
||||||
import lib::llvm::ValueRef;
|
import lib::llvm::ValueRef;
|
||||||
import common::*;
|
import common::*;
|
||||||
import build::*;
|
import build::*;
|
||||||
import base::{
|
import base::*;
|
||||||
trans_shared_malloc,
|
import shape::size_of;
|
||||||
type_of,
|
|
||||||
INIT,
|
|
||||||
trans_shared_free,
|
|
||||||
drop_ty,
|
|
||||||
new_sub_block_ctxt,
|
|
||||||
load_if_immediate,
|
|
||||||
dest
|
|
||||||
};
|
|
||||||
import shape::{size_of};
|
|
||||||
|
|
||||||
export trans_uniq, make_free_glue, autoderef, duplicate, alloc_uniq;
|
export trans_uniq, make_free_glue, autoderef, duplicate, alloc_uniq;
|
||||||
|
|
||||||
fn trans_uniq(bcx: @block_ctxt, contents: @ast::expr,
|
fn trans_uniq(bcx: block, contents: @ast::expr,
|
||||||
node_id: ast::node_id, dest: dest) -> @block_ctxt {
|
node_id: ast::node_id, dest: dest) -> block {
|
||||||
let uniq_ty = node_id_type(bcx, node_id);
|
let uniq_ty = node_id_type(bcx, node_id);
|
||||||
let {bcx, val: llptr} = alloc_uniq(bcx, uniq_ty);
|
let {bcx, val: llptr} = alloc_uniq(bcx, uniq_ty);
|
||||||
add_clean_free(bcx, llptr, true);
|
add_clean_free(bcx, llptr, true);
|
||||||
bcx = base::trans_expr_save_in(bcx, contents, llptr);
|
bcx = trans_expr_save_in(bcx, contents, llptr);
|
||||||
revoke_clean(bcx, llptr);
|
revoke_clean(bcx, llptr);
|
||||||
ret base::store_in_dest(bcx, llptr, dest);
|
ret store_in_dest(bcx, llptr, dest);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn alloc_uniq(cx: @block_ctxt, uniq_ty: ty::t) -> result {
|
fn alloc_uniq(cx: block, uniq_ty: ty::t) -> result {
|
||||||
let bcx = cx;
|
let bcx = cx;
|
||||||
let contents_ty = content_ty(uniq_ty);
|
let contents_ty = content_ty(uniq_ty);
|
||||||
let r = size_of(bcx, contents_ty);
|
let r = size_of(bcx, contents_ty);
|
||||||
|
@ -42,19 +33,12 @@ fn alloc_uniq(cx: @block_ctxt, uniq_ty: ty::t) -> result {
|
||||||
ret rslt(bcx, llptr);
|
ret rslt(bcx, llptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn make_free_glue(cx: @block_ctxt, vptr: ValueRef, t: ty::t)
|
fn make_free_glue(bcx: block, vptr: ValueRef, t: ty::t)
|
||||||
-> @block_ctxt {
|
-> block {
|
||||||
let bcx = cx;
|
with_cond(bcx, IsNotNull(bcx, vptr)) {|bcx|
|
||||||
let free_cx = new_sub_block_ctxt(bcx, "uniq_free");
|
let bcx = drop_ty(bcx, vptr, content_ty(t));
|
||||||
let next_cx = new_sub_block_ctxt(bcx, "uniq_free_next");
|
trans_shared_free(bcx, vptr)
|
||||||
let null_test = IsNull(bcx, vptr);
|
}
|
||||||
CondBr(bcx, null_test, next_cx.llbb, free_cx.llbb);
|
|
||||||
|
|
||||||
let bcx = free_cx;
|
|
||||||
let bcx = drop_ty(bcx, vptr, content_ty(t));
|
|
||||||
let bcx = trans_shared_free(bcx, vptr);
|
|
||||||
Br(bcx, next_cx.llbb);
|
|
||||||
next_cx
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn content_ty(t: ty::t) -> ty::t {
|
fn content_ty(t: ty::t) -> ty::t {
|
||||||
|
@ -69,12 +53,12 @@ fn autoderef(v: ValueRef, t: ty::t) -> {v: ValueRef, t: ty::t} {
|
||||||
ret {v: v, t: content_ty};
|
ret {v: v, t: content_ty};
|
||||||
}
|
}
|
||||||
|
|
||||||
fn duplicate(bcx: @block_ctxt, v: ValueRef, t: ty::t) -> result {
|
fn duplicate(bcx: block, v: ValueRef, t: ty::t) -> result {
|
||||||
let content_ty = content_ty(t);
|
let content_ty = content_ty(t);
|
||||||
let {bcx, val: llptr} = alloc_uniq(bcx, t);
|
let {bcx, val: llptr} = alloc_uniq(bcx, t);
|
||||||
|
|
||||||
let src = load_if_immediate(bcx, v, content_ty);
|
let src = load_if_immediate(bcx, v, content_ty);
|
||||||
let dst = llptr;
|
let dst = llptr;
|
||||||
let bcx = base::copy_val(bcx, INIT, dst, src, content_ty);
|
let bcx = copy_val(bcx, INIT, dst, src, content_ty);
|
||||||
ret rslt(bcx, dst);
|
ret rslt(bcx, dst);
|
||||||
}
|
}
|
|
@ -186,11 +186,8 @@ pure fn head<T: copy>(v: [const T]) : is_not_empty(v) -> T { ret v[0]; }
|
||||||
Function: tail
|
Function: tail
|
||||||
|
|
||||||
Returns all but the first element of a vector
|
Returns all but the first element of a vector
|
||||||
|
|
||||||
Predicates:
|
|
||||||
<is_not_empty> (v)
|
|
||||||
*/
|
*/
|
||||||
fn tail<T: copy>(v: [const T]) : is_not_empty(v) -> [T] {
|
fn tail<T: copy>(v: [const T]) -> [T] {
|
||||||
ret slice(v, 1u, len(v));
|
ret slice(v, 1u, len(v));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue