Move expr_lit and expr_vec into trans_expr_dps

Issue #667
This commit is contained in:
Marijn Haverbeke 2011-09-27 08:42:27 +02:00
parent 8ea72fae99
commit 806e74fbf5
3 changed files with 54 additions and 32 deletions

View file

@ -2153,10 +2153,16 @@ fn trans_crate_lit(cx: @crate_ctxt, lit: ast::lit) -> ValueRef {
}
}
fn trans_lit(cx: @block_ctxt, lit: ast::lit) -> result {
fn trans_lit(cx: @block_ctxt, lit: ast::lit, dest: dest) -> @block_ctxt {
if dest == ignore { ret cx; }
alt lit.node {
ast::lit_str(s) { ret tvec::trans_str(cx, s); }
_ { ret rslt(cx, trans_crate_lit(bcx_ccx(cx), lit)); }
ast::lit_str(s) { ret tvec::trans_str(cx, s, dest); }
_ {
let cell = alt dest { by_val(c) { c }
_ { bcx_ccx(cx).sess.span_note(lit.span, "here"); fail; }};
*cell = trans_crate_lit(bcx_ccx(cx), lit);
ret cx;
}
}
}
@ -4129,7 +4135,6 @@ fn trans_rec(bcx: @block_ctxt, fields: [ast::field],
fn trans_expr(cx: @block_ctxt, e: @ast::expr) -> result {
// Fixme Fill in cx.sp
alt e.node {
ast::expr_lit(lit) { ret trans_lit(cx, *lit); }
ast::expr_binary(op, x, y) { ret trans_binary(cx, op, x, y); }
ast::expr_fn(f) {
let ccx = bcx_ccx(cx);
@ -4186,7 +4191,6 @@ fn trans_expr(cx: @block_ctxt, e: @ast::expr) -> result {
}
ast::expr_bind(f, args) { ret trans_bind(cx, f, args, e.id); }
ast::expr_cast(val, _) { ret trans_cast(cx, val, e.id); }
ast::expr_vec(args, _) { ret tvec::trans_vec(cx, args, e.id); }
ast::expr_anon_obj(anon_obj) {
ret trans_anon_obj(cx, e.span, anon_obj, e.id);
}
@ -4261,6 +4265,9 @@ fn trans_expr_dps(bcx: @block_ctxt, e: @ast::expr, dest: dest)
ret trans_rec(bcx, args, base, e.id, dest);
}
ast::expr_tup(args) { ret trans_tup(bcx, args, e.id, dest); }
ast::expr_lit(lit) { ret trans_lit(bcx, *lit, dest); }
ast::expr_vec(args, _) { ret tvec::trans_vec(bcx, args, e.id, dest); }
ast::expr_break. {
assert dest == ignore;
ret trans_break(e.span, bcx);
@ -5306,13 +5313,18 @@ fn trans_closure(bcx_maybe: option::t<@block_ctxt>,
// translation calls that don't have a return value (trans_crate,
// trans_mod, trans_item, trans_obj, et cetera) and those that do
// (trans_block, trans_expr, et cetera).
let dest = if !ty::type_is_bot(cx.ccx.tcx, block_ty) &&
!ty::type_is_nil(cx.ccx.tcx, block_ty) &&
f.proto != ast::proto_iter &&
option::is_some(f.body.node.expr) {
save_in(fcx.llretptr)
} else { ignore };
bcx = trans_block_dps(bcx, f.body, dest);
if ty::type_is_bot(cx.ccx.tcx, block_ty) ||
ty::type_is_nil(cx.ccx.tcx, block_ty) ||
f.proto == ast::proto_iter ||
option::is_none(f.body.node.expr) {
bcx = trans_block_dps(bcx, f.body, ignore);
} else if type_is_immediate(cx.ccx, block_ty) {
let cell = empty_dest_cell();
bcx = trans_block_dps(bcx, f.body, by_val(cell));
Store(bcx, *cell, fcx.llretptr);
} else {
bcx = trans_block_dps(bcx, f.body, save_in(fcx.llretptr));
}
if !bcx.unreachable {
// FIXME: until LLVM has a unit type, we are moving around

View file

@ -33,7 +33,19 @@ fn opt_eq(a: opt, b: opt) -> bool {
}
fn trans_opt(bcx: @block_ctxt, o: opt) -> result {
alt o {
lit(l) { ret trans::trans_lit(bcx, *l); }
lit(l) {
alt l.node {
ast::lit_str(s) {
let {bcx, val: dst} =
trans::alloc_ty(bcx, ty::mk_str(bcx_tcx(bcx)));
bcx = trans_vec::trans_str(bcx, s, trans::save_in(dst));
ret rslt(bcx, dst);
}
_ {
ret rslt(bcx, trans::trans_crate_lit(bcx_ccx(bcx), *l));
}
}
}
var(id, _) { ret rslt(bcx, C_int(id as int)); }
}
}

View file

@ -8,7 +8,7 @@ import trans::{call_memmove, trans_shared_malloc, llsize_of, type_of_or_i8,
llderivedtydescs_block_ctxt, lazily_emit_tydesc_glue,
get_tydesc, load_inbounds, move_val_if_temp, trans_lval,
node_id_type, new_sub_block_ctxt, tps_normal, do_spill_noroot,
GEPi, alloc_ty};
GEPi, alloc_ty, dest};
import trans_build::*;
import trans_common::*;
@ -49,7 +49,8 @@ type alloc_result =
llunitsz: ValueRef,
llunitty: TypeRef};
fn alloc(bcx: @block_ctxt, vec_ty: ty::t, elts: uint) -> alloc_result {
fn alloc(bcx: @block_ctxt, vec_ty: ty::t, elts: uint, dest: dest)
-> alloc_result {
let unit_ty = ty::sequence_element_type(bcx_tcx(bcx), vec_ty);
let llunitty = type_of_or_i8(bcx, unit_ty);
let llvecty = T_vec(llunitty);
@ -60,12 +61,9 @@ fn alloc(bcx: @block_ctxt, vec_ty: ty::t, elts: uint) -> alloc_result {
let {bcx: bcx, val: vptr} = alloc_raw(bcx, fill, alloc);
let vptr = PointerCast(bcx, vptr, T_ptr(llvecty));
let r = alloc_ty(bcx, vec_ty);
let vptrptr = r.val;
bcx = r.bcx;
let vptrptr = alt dest { trans::save_in(a) { a } };
Store(bcx, vptr, vptrptr);
add_clean_temp(bcx, vptrptr, vec_ty);
// add_clean_temp(bcx, vptrptr, vec_ty);
ret {bcx: bcx,
val: vptrptr,
unit_ty: unit_ty,
@ -102,18 +100,19 @@ fn make_drop_glue(bcx: @block_ctxt, vptrptr: ValueRef, vec_ty: ty::t) ->
ret next_cx;
}
fn trans_vec(bcx: @block_ctxt, args: [@ast::expr], id: ast::node_id) ->
result {
// FIXME handle dest == ignore
fn trans_vec(bcx: @block_ctxt, args: [@ast::expr], id: ast::node_id,
dest: dest) -> @block_ctxt {
let vec_ty = node_id_type(bcx_ccx(bcx), id);
let {bcx: bcx,
val: vptr,
val: vptrptr,
llunitsz: llunitsz,
unit_ty: unit_ty,
llunitty: llunitty} =
alloc(bcx, vec_ty, vec::len(args));
alloc(bcx, vec_ty, vec::len(args), dest);
// Store the individual elements.
let dataptr = get_dataptr(bcx, vptr, llunitty);
let dataptr = get_dataptr(bcx, vptrptr, llunitty);
let i = 0u;
for e in args {
let lv = trans_lval(bcx, e);
@ -125,19 +124,18 @@ fn trans_vec(bcx: @block_ctxt, args: [@ast::expr], id: ast::node_id) ->
bcx = move_val_if_temp(bcx, INIT, lleltptr, lv, unit_ty);
i += 1u;
}
ret rslt(bcx, vptr);
ret bcx;
}
fn trans_str(bcx: @block_ctxt, s: str) -> result {
fn trans_str(bcx: @block_ctxt, s: str, dest: dest) -> @block_ctxt {
let veclen = std::str::byte_len(s) + 1u; // +1 for \0
let {bcx: bcx, val: sptr, _} =
alloc(bcx, ty::mk_str(bcx_tcx(bcx)), veclen);
let {bcx: bcx, val: sptrptr, _} =
alloc(bcx, ty::mk_str(bcx_tcx(bcx)), veclen, dest);
let llcstr = C_cstr(bcx_ccx(bcx), s);
let bcx =
call_memmove(bcx, get_dataptr(bcx, sptr, T_i8()), llcstr,
call_memmove(bcx, get_dataptr(bcx, sptrptr, T_i8()), llcstr,
C_uint(veclen)).bcx;
ret rslt(bcx, sptr);
ret bcx;
}
fn trans_append(cx: @block_ctxt, vec_ty: ty::t, lhsptr: ValueRef,