thread the context through so that int can be 64 bits on x86_64

This commit is contained in:
Niko Matsakis 2011-10-14 20:38:24 -07:00 committed by Brian Anderson
parent 2521cda1ec
commit c0e9c42bd2
7 changed files with 149 additions and 99 deletions

View File

@ -1,5 +1,6 @@
import std::str;
import driver::session;
import middle::trans;
import trans::decl_cdecl_fn;
import middle::trans_common::{T_f32, T_f64, T_fn, T_bool, T_i1, T_i8, T_i32,
@ -32,7 +33,9 @@ type upcalls =
call_c_stack_float: ValueRef,
rust_personality: ValueRef};
fn declare_upcalls(_tn: type_names, tydesc_type: TypeRef,
fn declare_upcalls(targ_cfg: @session::config,
_tn: type_names,
tydesc_type: TypeRef,
llmod: ModuleRef) -> @upcalls {
fn decl(llmod: ModuleRef, name: str, tys: [TypeRef], rv: TypeRef) ->
ValueRef {
@ -44,25 +47,35 @@ fn declare_upcalls(_tn: type_names, tydesc_type: TypeRef,
let d = bind decl(llmod, _, _, _);
let dv = bind decl(llmod, _, _, T_void());
ret @{_fail: dv("fail", [T_ptr(T_i8()), T_ptr(T_i8()), T_size_t()]),
let int_t = T_int(targ_cfg);
let size_t = T_size_t(targ_cfg);
let opaque_vec_t = T_opaque_vec(targ_cfg);
ret @{_fail: dv("fail", [T_ptr(T_i8()),
T_ptr(T_i8()),
size_t]),
malloc:
d("malloc", [T_size_t(), T_ptr(tydesc_type)], T_ptr(T_i8())),
free: dv("free", [T_ptr(T_i8()), T_int()]),
d("malloc", [size_t, T_ptr(tydesc_type)],
T_ptr(T_i8())),
free: dv("free", [T_ptr(T_i8()), int_t]),
shared_malloc:
d("shared_malloc", [T_size_t(), T_ptr(tydesc_type)],
d("shared_malloc", [size_t, T_ptr(tydesc_type)],
T_ptr(T_i8())),
shared_free: dv("shared_free", [T_ptr(T_i8())]),
mark: d("mark", [T_ptr(T_i8())], T_int()),
mark: d("mark", [T_ptr(T_i8())], int_t),
get_type_desc:
d("get_type_desc",
[T_ptr(T_nil()), T_size_t(), T_size_t(), T_size_t(),
T_ptr(T_ptr(tydesc_type)), T_int()], T_ptr(tydesc_type)),
[T_ptr(T_nil()), size_t,
size_t, size_t,
T_ptr(T_ptr(tydesc_type)), int_t],
T_ptr(tydesc_type)),
vec_grow:
dv("vec_grow", [T_ptr(T_ptr(T_opaque_vec())), T_int()]),
dv("vec_grow", [T_ptr(T_ptr(opaque_vec_t)),
int_t]),
vec_push:
dv("vec_push",
[T_ptr(T_ptr(T_opaque_vec())), T_ptr(tydesc_type),
T_ptr(T_i8())]),
[T_ptr(T_ptr(opaque_vec_t)), T_ptr(tydesc_type),
T_ptr(T_i8())]),
cmp_type:
dv("cmp_type",
[T_ptr(T_i1()), T_ptr(tydesc_type),
@ -72,13 +85,13 @@ fn declare_upcalls(_tn: type_names, tydesc_type: TypeRef,
dv("log_type", [T_ptr(tydesc_type), T_ptr(T_i8()), T_i32()]),
dynastack_mark: d("dynastack_mark", [], T_ptr(T_i8())),
dynastack_alloc:
d("dynastack_alloc_2", [T_size_t(), T_ptr(tydesc_type)],
d("dynastack_alloc_2", [size_t, T_ptr(tydesc_type)],
T_ptr(T_i8())),
dynastack_free: dv("dynastack_free", [T_ptr(T_i8())]),
alloc_c_stack: d("alloc_c_stack", [T_size_t()], T_ptr(T_i8())),
call_c_stack: d("call_c_stack",
[T_ptr(T_fn([], T_int())), T_ptr(T_i8())],
T_int()),
int_t),
call_c_stack_i64: d("call_c_stack_i64",
[T_ptr(T_fn([], T_int())), T_ptr(T_i8())],
T_i64()),

View File

@ -29,6 +29,7 @@ fn add_global(ccx: @crate_ctxt, llval: ValueRef, name: str) -> ValueRef {
fn add_gc_root(cx: @block_ctxt, llval: ValueRef, ty: ty::t) -> @block_ctxt {
let bcx = cx;
let ccx = bcx_ccx(cx);
if !type_is_gc_relevant(bcx_tcx(cx), ty) ||
ty::type_has_dynamic_size(bcx_tcx(cx), ty) {
ret bcx;
@ -61,10 +62,12 @@ fn add_gc_root(cx: @block_ctxt, llval: ValueRef, ty: ty::t) -> @block_ctxt {
gc_cx.next_tydesc_num += 1u;
let lldestindex =
add_global(bcx_ccx(bcx), C_struct([C_int(0), C_uint(number)]),
add_global(bcx_ccx(bcx), C_struct([C_int(ccx, 0),
C_uint(ccx, number)]),
"rust_gc_tydesc_dest_index");
let llsrcindex =
add_global(bcx_ccx(bcx), C_struct([C_int(1), C_uint(number)]),
add_global(bcx_ccx(bcx), C_struct([C_int(ccx, 1),
C_uint(ccx, number)]),
"rust_gc_tydesc_src_index");
lldestindex = lll::LLVMConstPointerCast(lldestindex, T_ptr(T_i8()));
@ -85,7 +88,7 @@ fn add_gc_root(cx: @block_ctxt, llval: ValueRef, ty: ty::t) -> @block_ctxt {
// Static type descriptor.
let llstaticgcmeta =
add_global(bcx_ccx(bcx), C_struct([C_int(2), lltydesc]),
add_global(bcx_ccx(bcx), C_struct([C_int(ccx, 2), lltydesc]),
"rust_gc_tydesc_static_gc_meta");
let llstaticgcmetaptr =
lll::LLVMConstPointerCast(llstaticgcmeta, T_ptr(T_i8()));

View File

@ -161,7 +161,7 @@ fn type_of_inner(cx: @crate_ctxt, sp: span, t: ty::t)
ty::ty_vec(mt) {
let mt_ty = mt.ty;
if ty::type_has_dynamic_size(cx.tcx, mt_ty) {
T_ptr(T_opaque_vec(cx))
T_ptr(cx.opaque_vec_type)
} else {
// should be unnecessary
check non_ty_var(cx, mt_ty);
@ -359,7 +359,7 @@ fn trans_native_call(cx: @block_ctxt, externs: hashmap<str, ValueRef>,
get_simple_extern_fn(cx, externs, llmod, name, n);
let call_args: [ValueRef] = [];
for a: ValueRef in args {
call_args += [ZExtOrBitCast(cx, a, T_int(bcx_ccx(cx)))];
call_args += [ZExtOrBitCast(cx, a, bcx_ccx(cx).int_type)];
}
ret Call(cx, llnative, call_args);
}
@ -2616,7 +2616,7 @@ fn trans_for(cx: @block_ctxt, local: @ast::local, seq: @ast::expr,
let next_cx = new_sub_block_ctxt(cx, "next");
let seq_ty = ty::expr_ty(bcx_tcx(cx), seq);
let {bcx: bcx, val: seq} = trans_temp_expr(cx, seq);
let seq = PointerCast(bcx, seq, T_ptr(T_opaque_vec(ccx)));
let seq = PointerCast(bcx, seq, T_ptr(ccx.opaque_vec_type));
let fill = tvec::get_fill(bcx, seq);
if ty::type_is_str(bcx_tcx(bcx), seq_ty) {
fill = Sub(bcx, fill, C_int(ccx, 1));
@ -6075,7 +6075,7 @@ fn fill_crate_map(ccx: @crate_ctxt, map: ValueRef) {
llvm::LLVMSetLinkage(map,
lib::llvm::LLVMExternalLinkage as llvm::Linkage);
llvm::LLVMSetInitializer(map,
C_struct([p2i(create_module_map(ccx)),
C_struct([p2i(ccx, create_module_map(ccx)),
C_array(ccx.int_type, subcrates)]));
ret map;
>>>>>>> work on making the size of ints depend on the target arch
@ -6129,15 +6129,16 @@ fn trans_crate(sess: session::session, crate: @ast::crate, tcx: ty::ctxt,
let _: () =
str::as_buf(sess.get_targ_cfg().target_strs.target_triple,
{|buf| llvm::LLVMSetTarget(llmod, buf) });
let targ_cfg = sess.get_targ_cfg();
let td = mk_target_data(sess.get_targ_cfg().target_strs.data_layout);
let tn = mk_type_names();
let intrinsics = declare_intrinsics(llmod);
let int_type = T_int(sess.get_targ_cfg().arch);
let float_type = T_float(sess.get_targ_cfg().arch);
let task_type = T_task(sess.get_targ_cfg().arch);
let int_type = T_int(targ_cfg);
let float_type = T_float(targ_cfg);
let task_type = T_task(targ_cfg);
let taskptr_type = T_ptr(task_type);
tn.associate("taskptr", taskptr_type);
let tydesc_type = T_tydesc(taskptr_type);
let tydesc_type = T_tydesc(targ_cfg, taskptr_type);
tn.associate("tydesc", tydesc_type);
let hasher = ty::hash_ty;
let eqer = ty::eq_ty;
@ -6184,12 +6185,14 @@ fn trans_crate(sess: session::session, crate: @ast::crate, tcx: ty::ctxt,
mutable n_real_glues: 0u,
fn_times: @mutable []},
upcalls:
upcall::declare_upcalls(tn, tydesc_type, llmod),
upcall::declare_upcalls(targ_cfg, tn, tydesc_type,
llmod),
rust_object_type: T_rust_object(),
tydesc_type: tydesc_type,
int_type: int_type,
float_type: float_type,
task_type: task_type,
opaque_vec_type: T_opaque_vec(targ_cfg),
builder: BuilderRef_res(llvm::LLVMCreateBuilder()),
shape_cx: shape::mk_ctxt(llmod),
gc_cx: gc::mk_ctxt(),

View File

@ -44,6 +44,7 @@ tag opt_result {
range_result(result, result);
}
fn trans_opt(bcx: @block_ctxt, o: opt) -> opt_result {
let ccx = bcx_ccx(bcx);
alt o {
lit(l) {
alt l.node {
@ -56,11 +57,11 @@ fn trans_opt(bcx: @block_ctxt, o: opt) -> opt_result {
}
_ {
ret single_result(
rslt(bcx, trans::trans_crate_lit(bcx_ccx(bcx), *l)));
rslt(bcx, trans::trans_crate_lit(ccx, *l)));
}
}
}
var(id, _) { ret single_result(rslt(bcx, C_int(id as int))); }
var(id, _) { ret single_result(rslt(bcx, C_int(ccx, id as int))); }
range(l1, l2) {
let cell1 = trans::empty_dest_cell();
let cell2 = trans::empty_dest_cell();
@ -257,8 +258,8 @@ fn extract_variant_args(bcx: @block_ctxt, pat_id: ast::node_id,
vec::len(ty::tag_variant_with_id(ccx.tcx, vdefs.tg, vdefs.var).args);
if size > 0u && vec::len(variants) != 1u {
let tagptr =
PointerCast(bcx, val, trans_common::T_opaque_tag_ptr(ccx.tn));
blobptr = GEP(bcx, tagptr, [C_int(0), C_int(1)]);
PointerCast(bcx, val, trans_common::T_opaque_tag_ptr(ccx));
blobptr = GEP(bcx, tagptr, [C_int(ccx, 0), C_int(ccx, 1)]);
}
let i = 0u;
let vdefs_tg = vdefs.tg;
@ -439,7 +440,8 @@ fn compile_submatch(bcx: @block_ctxt, m: match, vals: [ValueRef], f: mk_fail,
let box = Load(bcx, val);
let unboxed =
InBoundsGEP(bcx, box,
[C_int(0), C_int(back::abi::box_rc_field_body)]);
[C_int(ccx, 0),
C_int(ccx, back::abi::box_rc_field_body)]);
compile_submatch(bcx, enter_box(m, col, val), [unboxed] + vals_left,
f, exits);
ret;
@ -465,8 +467,9 @@ fn compile_submatch(bcx: @block_ctxt, m: match, vals: [ValueRef], f: mk_fail,
} else {
let tagptr =
PointerCast(bcx, val,
trans_common::T_opaque_tag_ptr(ccx.tn));
let discrimptr = GEP(bcx, tagptr, [C_int(0), C_int(0)]);
trans_common::T_opaque_tag_ptr(ccx));
let discrimptr = GEP(bcx, tagptr, [C_int(ccx, 0),
C_int(ccx, 0)]);
test_val = Load(bcx, discrimptr);
kind = switch;
}
@ -505,7 +508,7 @@ fn compile_submatch(bcx: @block_ctxt, m: match, vals: [ValueRef], f: mk_fail,
// holding a corrupted value (when the compiler is optimized).
// This can be removed after our next LLVM upgrade.
val_ty(sw);
} else { sw = C_int(0); } // Placeholder for when not using a switch
} else { sw = C_int(ccx, 0); } // Placeholder for when not using a switch
// Compile subtrees for each option
for opt: opt in opts {
@ -736,7 +739,8 @@ fn bind_irrefutable_pat(bcx: @block_ctxt, pat: @ast::pat, val: ValueRef,
let box = Load(bcx, val);
let unboxed =
InBoundsGEP(bcx, box,
[C_int(0), C_int(back::abi::box_rc_field_body)]);
[C_int(ccx, 0),
C_int(ccx, back::abi::box_rc_field_body)]);
bcx = bind_irrefutable_pat(bcx, inner, unboxed, true);
}
ast::pat_uniq(inner) {

View File

@ -123,6 +123,7 @@ type crate_ctxt =
int_type: TypeRef,
float_type: TypeRef,
task_type: TypeRef,
opaque_vec_type: TypeRef,
builder: BuilderRef_res,
shape_cx: shape::ctxt,
gc_cx: gc::ctxt,
@ -490,26 +491,26 @@ fn T_f64() -> TypeRef { ret llvm::LLVMDoubleType(); }
fn T_bool() -> TypeRef { ret T_i1(); }
fn T_int(arch: session::arch) -> TypeRef {
ret alt arch {
arch_x86 { T_i32() }
arch_x86_64 { T_i64() }
arch_arm { T_i32() }
fn T_int(targ_cfg: @session::config) -> TypeRef {
ret alt targ_cfg.arch {
session::arch_x86. { T_i32() }
session::arch_x86_64. { T_i64() }
session::arch_arm. { T_i32() }
};
}
fn T_float(arch: session::arch) -> TypeRef {
ret alt arch {
arch_x86 { T_f64() }
arch_x86_64 { T_f64() }
arch_arm { T_f64() }
fn T_float(targ_cfg: @session::config) -> TypeRef {
ret alt targ_cfg.arch {
session::arch_x86. { T_f64() }
session::arch_x86_64. { T_f64() }
session::arch_arm. { T_f64() }
};
}
fn T_char() -> TypeRef { ret T_i32(); }
fn T_size_t(cx: @crate_ctxt) -> TypeRef {
ret cx.int_type;
fn T_size_t(targ_cfg: @session::config) -> TypeRef {
ret T_int(targ_cfg);
}
fn T_fn(inputs: [TypeRef], output: TypeRef) -> TypeRef {
@ -553,7 +554,7 @@ fn T_rust_object() -> TypeRef {
ret t;
}
fn T_task(arch: session::arch) -> TypeRef {
fn T_task(targ_cfg: @session::config) -> TypeRef {
let t = T_named_struct("task");
// Refcount
@ -567,7 +568,7 @@ fn T_task(arch: session::arch) -> TypeRef {
// Domain pointer
// Crate cache pointer
let t_int = T_int(arch);
let t_int = T_int(targ_cfg);
let elems =
[t_int, t_int, t_int, t_int,
t_int, t_int, t_int, t_int];
@ -603,7 +604,7 @@ fn T_cmp_glue_fn(cx: @crate_ctxt) -> TypeRef {
ret t;
}
fn T_tydesc(cx: @crate_ctxt) -> TypeRef {
fn T_tydesc(targ_cfg: @session::config) -> TypeRef {
let tydesc = T_named_struct("tydesc");
let tydescpp = T_ptr(T_ptr(tydesc));
let pvoid = T_ptr(T_i8());
@ -614,29 +615,35 @@ fn T_tydesc(cx: @crate_ctxt) -> TypeRef {
T_ptr(T_fn([T_ptr(T_i1()), T_ptr(tydesc), tydescpp,
pvoid, pvoid, T_i8()], T_void()));
let int_type = T_int(targ_cfg);
let elems =
[tydescpp, cx.int_type, cx.int_type,
[tydescpp, int_type, int_type,
glue_fn_ty, glue_fn_ty, glue_fn_ty,
T_ptr(T_i8()), glue_fn_ty, glue_fn_ty, glue_fn_ty, cmp_glue_fn_ty,
T_ptr(T_i8()), T_ptr(T_i8()), cx.int_type, cx.int_type];
T_ptr(T_i8()), T_ptr(T_i8()), int_type, int_type];
set_struct_body(tydesc, elems);
ret tydesc;
}
fn T_array(t: TypeRef, n: uint) -> TypeRef { ret llvm::LLVMArrayType(t, n); }
// Interior vector.
//
// TODO: Support user-defined vector sizes.
fn T_vec(cx: @crate_ctxt, t: TypeRef) -> TypeRef {
ret T_struct([cx.int_type, // fill
cx.int_type, // alloc
fn T_vec2(targ_cfg: @session::config, t: TypeRef) -> TypeRef {
ret T_struct([T_int(targ_cfg), // fill
T_int(targ_cfg), // alloc
T_array(t, 0u)]); // elements
}
fn T_vec(ccx: @crate_ctxt, t: TypeRef) -> TypeRef {
ret T_vec2(ccx.sess.get_targ_cfg(), t);
}
// Note that the size of this one is in bytes.
fn T_opaque_vec(cx: @crate_ctxt) -> TypeRef { ret T_vec(cx, T_i8()); }
fn T_opaque_vec(targ_cfg: @session::config) -> TypeRef {
ret T_vec2(targ_cfg, T_i8());
}
fn T_box(cx: @crate_ctxt, t: TypeRef) -> TypeRef {
ret T_struct([cx.int_type, t]);

View File

@ -70,8 +70,8 @@ fn trans_obj(cx: @local_ctxt, sp: span, ob: ast::_obj, ctor_id: ast::node_id,
// Grab onto the first and second elements of the pair.
// abi::obj_field_vtbl and abi::obj_field_box simply specify words 0 and 1
// of 'pair'.
let pair_vtbl = GEP(bcx, pair, [C_int(0), C_int(abi::obj_field_vtbl)]);
let pair_box = GEP(bcx, pair, [C_int(0), C_int(abi::obj_field_box)]);
let pair_vtbl = GEPi(bcx, pair, [0, abi::obj_field_vtbl]);
let pair_box = GEPi(bcx, pair, [0, abi::obj_field_box]);
// Make a vtable for this object: a static array of pointers to functions.
// It will be located in the read-only memory of the executable we're
@ -375,9 +375,9 @@ fn trans_anon_obj(bcx: @block_ctxt, sp: span, anon_obj: ast::anon_obj,
box = PointerCast(bcx, box, llbox_ty);
}
let pair = trans::get_dest_addr(dest);
let pair_vtbl = GEP(bcx, pair, [C_int(0), C_int(abi::obj_field_vtbl)]);
let pair_vtbl = GEPi(bcx, pair, [0, abi::obj_field_vtbl]);
Store(bcx, vtbl, pair_vtbl);
let pair_box = GEP(bcx, pair, [C_int(0), C_int(abi::obj_field_box)]);
let pair_box = GEPi(bcx, pair, [0, abi::obj_field_box]);
Store(bcx, box, pair_box);
ret bcx;
}
@ -627,7 +627,7 @@ fn process_bkwding_mthd(cx: @local_ctxt, sp: span, m: @ty::method,
PointerCast(bcx, fcx.llenv,
T_ptr(T_struct([cx.ccx.rust_object_type,
T_ptr(cx.ccx.rust_object_type)])));
let llself_obj_ptr = GEP(bcx, llenv, [C_int(0), C_int(1)]);
let llself_obj_ptr = GEPi(bcx, llenv, [0, 1]);
llself_obj_ptr = Load(bcx, llself_obj_ptr);
// Cast it back to pointer-to-object-type, so LLVM won't complain.
@ -663,12 +663,12 @@ fn process_bkwding_mthd(cx: @local_ctxt, sp: span, m: @ty::method,
let vtbl_type = T_ptr(T_array(T_ptr(T_nil()), ix + 1u));
let llouter_obj_vtbl =
GEP(bcx, llself_obj_ptr, [C_int(0), C_int(abi::obj_field_vtbl)]);
GEPi(bcx, llself_obj_ptr, [0, abi::obj_field_vtbl]);
llouter_obj_vtbl = Load(bcx, llouter_obj_vtbl);
llouter_obj_vtbl = PointerCast(bcx, llouter_obj_vtbl, vtbl_type);
let llouter_mthd =
GEP(bcx, llouter_obj_vtbl, [C_int(0), C_int(ix as int)]);
GEPi(bcx, llouter_obj_vtbl, [0, ix as int]);
// Set up the outer method to be called.
let llouter_mthd_ty = type_of_meth(bcx_ccx(bcx), sp, m, ty_params);
@ -746,16 +746,16 @@ fn process_fwding_mthd(cx: @local_ctxt, sp: span, m: @ty::method,
// First, grab the box out of the self_obj. It contains a refcount and a
// body.
let llself_obj_box =
GEP(bcx, llself_obj_ptr, [C_int(0), C_int(abi::obj_field_box)]);
GEPi(bcx, llself_obj_ptr, [0, abi::obj_field_box]);
llself_obj_box = Load(bcx, llself_obj_box);
let ccx = bcx_ccx(bcx);
let llbox_ty = T_opaque_obj_ptr(*ccx);
let llbox_ty = T_opaque_obj_ptr(ccx);
llself_obj_box = PointerCast(bcx, llself_obj_box, llbox_ty);
// Now, reach into the box and grab the body.
let llself_obj_body =
GEP(bcx, llself_obj_box, [C_int(0), C_int(abi::box_rc_field_body)]);
GEPi(bcx, llself_obj_box, [0, abi::box_rc_field_body]);
// Now, we need to figure out exactly what type the body is supposed to be
// cast to.
@ -784,11 +784,11 @@ fn process_fwding_mthd(cx: @local_ctxt, sp: span, m: @ty::method,
// method's entry out of the vtable so that the forwarding function can
// call it.
let llinner_obj_vtbl =
GEP(bcx, llinner_obj.val, [C_int(0), C_int(abi::obj_field_vtbl)]);
GEPi(bcx, llinner_obj.val, [0, abi::obj_field_vtbl]);
llinner_obj_vtbl = Load(bcx, llinner_obj_vtbl);
let llinner_obj_body =
GEP(bcx, llinner_obj.val, [C_int(0), C_int(abi::obj_field_box)]);
GEPi(bcx, llinner_obj.val, [0, abi::obj_field_box]);
llinner_obj_body = Load(bcx, llinner_obj_body);
// Get the index of the method we want.
@ -809,7 +809,7 @@ fn process_fwding_mthd(cx: @local_ctxt, sp: span, m: @ty::method,
llinner_obj_vtbl = PointerCast(bcx, llinner_obj_vtbl, vtbl_type);
let llorig_mthd =
GEP(bcx, llinner_obj_vtbl, [C_int(0), C_int(ix as int)]);
GEPi(bcx, llinner_obj_vtbl, [0, ix as int]);
// Set up the original method to be called.
let llorig_mthd_ty = type_of_meth(bcx_ccx(bcx), sp, m, ty_params);
@ -920,18 +920,18 @@ fn populate_self_stack(bcx: @block_ctxt, self_stack: ValueRef,
inner_obj_body: ValueRef) -> ValueRef {
// Drop the outer obj into the second slot.
let self_pair_ptr = GEP(bcx, self_stack, [C_int(0), C_int(1)]);
let self_pair_ptr = GEPi(bcx, self_stack, [0, 1]);
Store(bcx, outer_obj, self_pair_ptr);
// Drop in the backwarding vtbl.
let wrapper_pair = GEP(bcx, self_stack, [C_int(0), C_int(0)]);
let wrapper_vtbl_ptr = GEP(bcx, wrapper_pair, [C_int(0), C_int(0)]);
let wrapper_pair = GEPi(bcx, self_stack, [0, 0]);
let wrapper_vtbl_ptr = GEPi(bcx, wrapper_pair, [0, 0]);
let backwarding_vtbl_cast =
PointerCast(bcx, backwarding_vtbl, T_ptr(T_empty_struct()));
Store(bcx, backwarding_vtbl_cast, wrapper_vtbl_ptr);
// Drop in the inner obj body.
let wrapper_body_ptr = GEP(bcx, wrapper_pair, [C_int(0), C_int(1)]);
let wrapper_body_ptr = GEPi(bcx, wrapper_pair, [0, 1]);
Store(bcx, inner_obj_body, wrapper_body_ptr);
ret self_stack;

View File

@ -28,14 +28,17 @@ fn pointer_add(bcx: @block_ctxt, ptr: ValueRef, bytes: ValueRef) -> ValueRef {
}
fn alloc_raw(bcx: @block_ctxt, fill: ValueRef, alloc: ValueRef) -> result {
let llvecty = T_opaque_vec();
let vecsize = Add(bcx, alloc, llsize_of(llvecty));
let ccx = bcx_ccx(bcx);
let llvecty = ccx.opaque_vec_type;
let vecsize = Add(bcx, alloc, llsize_of(ccx, llvecty));
let {bcx: bcx, val: vecptr} =
trans_shared_malloc(bcx, T_ptr(llvecty), vecsize);
Store(bcx, fill,
InBoundsGEP(bcx, vecptr, [C_int(0), C_uint(abi::vec_elt_fill)]));
InBoundsGEP(bcx, vecptr, [C_int(ccx, 0),
C_uint(ccx, abi::vec_elt_fill)]));
Store(bcx, alloc,
InBoundsGEP(bcx, vecptr, [C_int(0), C_uint(abi::vec_elt_alloc)]));
InBoundsGEP(bcx, vecptr, [C_int(ccx, 0),
C_uint(ccx, abi::vec_elt_alloc)]));
ret {bcx: bcx, val: vecptr};
}
@ -47,13 +50,18 @@ type alloc_result =
llunitty: TypeRef};
fn alloc(bcx: @block_ctxt, vec_ty: ty::t, elts: uint) -> alloc_result {
let ccx = bcx_ccx(bcx);
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);
let llvecty = T_vec(ccx, llunitty);
let {bcx: bcx, val: unit_sz} = size_of(bcx, unit_ty);
let fill = Mul(bcx, C_uint(elts), unit_sz);
let alloc = if elts < 4u { Mul(bcx, C_int(4), unit_sz) } else { fill };
let fill = Mul(bcx, C_uint(ccx, elts), unit_sz);
let alloc = if elts < 4u {
Mul(bcx, C_int(ccx, 4), unit_sz)
} else {
fill
};
let {bcx: bcx, val: vptr} = alloc_raw(bcx, fill, alloc);
let vptr = PointerCast(bcx, vptr, T_ptr(llvecty));
@ -65,14 +73,16 @@ fn alloc(bcx: @block_ctxt, vec_ty: ty::t, elts: uint) -> alloc_result {
}
fn duplicate(bcx: @block_ctxt, vptr: ValueRef, vec_ty: ty::t) -> result {
let ccx = bcx_ccx(bcx);
let fill = get_fill(bcx, vptr);
let size = Add(bcx, fill, llsize_of(T_opaque_vec()));
let size = Add(bcx, fill, llsize_of(ccx, ccx.opaque_vec_type));
let {bcx: bcx, val: newptr} =
trans_shared_malloc(bcx, val_ty(vptr), size);
let bcx = call_memmove(bcx, newptr, vptr, size).bcx;
let unit_ty = ty::sequence_element_type(bcx_tcx(bcx), vec_ty);
Store(bcx, fill,
InBoundsGEP(bcx, newptr, [C_int(0), C_uint(abi::vec_elt_alloc)]));
InBoundsGEP(bcx, newptr, [C_int(ccx, 0),
C_uint(ccx, abi::vec_elt_alloc)]));
if ty::type_needs_drop(bcx_tcx(bcx), unit_ty) {
bcx = iter_vec(bcx, newptr, vec_ty, trans::take_ty);
}
@ -95,6 +105,7 @@ fn make_free_glue(bcx: @block_ctxt, vptr: ValueRef, vec_ty: ty::t) ->
fn trans_vec(bcx: @block_ctxt, args: [@ast::expr], id: ast::node_id,
dest: dest) -> @block_ctxt {
let ccx = bcx_ccx(bcx);
if dest == trans::ignore {
for arg in args {
bcx = trans::trans_expr(bcx, arg, trans::ignore);
@ -115,8 +126,8 @@ fn trans_vec(bcx: @block_ctxt, args: [@ast::expr], id: ast::node_id,
let i = 0u, temp_cleanups = [vptr];
for e in args {
let lleltptr = if ty::type_has_dynamic_size(bcx_tcx(bcx), unit_ty) {
InBoundsGEP(bcx, dataptr, [Mul(bcx, C_uint(i), llunitsz)])
} else { InBoundsGEP(bcx, dataptr, [C_uint(i)]) };
InBoundsGEP(bcx, dataptr, [Mul(bcx, C_uint(ccx, i), llunitsz)])
} else { InBoundsGEP(bcx, dataptr, [C_uint(ccx, i)]) };
bcx = trans::trans_expr_save_in(bcx, e, lleltptr);
add_clean_temp_mem(bcx, lleltptr, unit_ty);
temp_cleanups += [lleltptr];
@ -131,21 +142,23 @@ fn trans_str(bcx: @block_ctxt, s: str, dest: dest) -> @block_ctxt {
let {bcx: bcx, val: sptr, _} =
alloc(bcx, ty::mk_str(bcx_tcx(bcx)), veclen);
let llcstr = C_cstr(bcx_ccx(bcx), s);
let ccx = bcx_ccx(bcx);
let llcstr = C_cstr(ccx, s);
let bcx =
call_memmove(bcx, get_dataptr(bcx, sptr, T_i8()), llcstr,
C_uint(veclen)).bcx;
C_uint(ccx, veclen)).bcx;
ret trans::store_in_dest(bcx, sptr, dest);
}
fn trans_append(cx: @block_ctxt, vec_ty: ty::t, lhsptr: ValueRef,
rhs: ValueRef) -> @block_ctxt {
// Cast to opaque interior vector types if necessary.
let ccx = bcx_ccx(cx);
let unit_ty = ty::sequence_element_type(bcx_tcx(cx), vec_ty);
let dynamic = ty::type_has_dynamic_size(bcx_tcx(cx), unit_ty);
if dynamic {
lhsptr = PointerCast(cx, lhsptr, T_ptr(T_ptr(T_opaque_vec())));
rhs = PointerCast(cx, rhs, T_ptr(T_opaque_vec()));
lhsptr = PointerCast(cx, lhsptr, T_ptr(T_ptr(ccx.opaque_vec_type)));
rhs = PointerCast(cx, rhs, T_ptr(ccx.opaque_vec_type));
}
let strings = alt ty::struct(bcx_tcx(cx), vec_ty) {
ty::ty_str. { true }
@ -160,8 +173,9 @@ fn trans_append(cx: @block_ctxt, vec_ty: ty::t, lhsptr: ValueRef,
let lfill = get_fill(bcx, lhs);
let rfill = get_fill(bcx, rhs);
let new_fill = Add(bcx, lfill, rfill);
if strings { new_fill = Sub(bcx, new_fill, C_int(1)); }
let opaque_lhs = PointerCast(bcx, lhsptr, T_ptr(T_ptr(T_opaque_vec())));
if strings { new_fill = Sub(bcx, new_fill, C_int(ccx, 1)); }
let opaque_lhs = PointerCast(bcx, lhsptr,
T_ptr(T_ptr(ccx.opaque_vec_type)));
Call(bcx, bcx_ccx(cx).upcalls.vec_grow,
[opaque_lhs, new_fill]);
// Was overwritten if we resized
@ -170,7 +184,7 @@ fn trans_append(cx: @block_ctxt, vec_ty: ty::t, lhsptr: ValueRef,
let lhs_data = get_dataptr(bcx, lhs, llunitty);
let lhs_off = lfill;
if strings { lhs_off = Sub(bcx, lhs_off, C_int(1)); }
if strings { lhs_off = Sub(bcx, lhs_off, C_int(ccx, 1)); }
let write_ptr = pointer_add(bcx, lhs_data, lhs_off);
let write_ptr_ptr = do_spill_noroot(bcx, write_ptr);
let bcx = iter_vec_raw(bcx, rhs, vec_ty, rfill,
@ -181,7 +195,7 @@ fn trans_append(cx: @block_ctxt, vec_ty: ty::t, lhsptr: ValueRef,
copy_val(bcx, INIT, write_ptr,
load_if_immediate(bcx, addr, unit_ty),
unit_ty);
let incr = dynamic ? unit_sz : C_int(1);
let incr = dynamic ? unit_sz : C_int(ccx, 1);
Store(bcx, InBoundsGEP(bcx, write_ptr, [incr]),
write_ptr_ptr);
ret bcx;
@ -191,12 +205,14 @@ fn trans_append(cx: @block_ctxt, vec_ty: ty::t, lhsptr: ValueRef,
fn trans_append_literal(bcx: @block_ctxt, vptrptr: ValueRef, vec_ty: ty::t,
vals: [@ast::expr]) -> @block_ctxt {
let ccx = bcx_ccx(bcx);
let elt_ty = ty::sequence_element_type(bcx_tcx(bcx), vec_ty);
let ti = none;
let {bcx: bcx, val: td} =
get_tydesc(bcx, elt_ty, false, tps_normal, ti).result;
trans::lazily_emit_tydesc_glue(bcx, abi::tydesc_field_take_glue, ti);
let opaque_v = PointerCast(bcx, vptrptr, T_ptr(T_ptr(T_opaque_vec())));
let opaque_v = PointerCast(bcx, vptrptr,
T_ptr(T_ptr(ccx.opaque_vec_type)));
for val in vals {
let {bcx: e_bcx, val: elt} = trans::trans_temp_expr(bcx, val);
bcx = e_bcx;
@ -211,6 +227,7 @@ fn trans_append_literal(bcx: @block_ctxt, vptrptr: ValueRef, vec_ty: ty::t,
fn trans_add(bcx: @block_ctxt, vec_ty: ty::t, lhs: ValueRef,
rhs: ValueRef, dest: dest) -> @block_ctxt {
let ccx = bcx_ccx(bcx);
let strings = alt ty::struct(bcx_tcx(bcx), vec_ty) {
ty::ty_str. { true }
ty::ty_vec(_) { false }
@ -220,11 +237,11 @@ fn trans_add(bcx: @block_ctxt, vec_ty: ty::t, lhs: ValueRef,
let {bcx: bcx, val: llunitsz} = size_of(bcx, unit_ty);
let lhs_fill = get_fill(bcx, lhs);
if strings { lhs_fill = Sub(bcx, lhs_fill, C_int(1)); }
if strings { lhs_fill = Sub(bcx, lhs_fill, C_int(ccx, 1)); }
let rhs_fill = get_fill(bcx, rhs);
let new_fill = Add(bcx, lhs_fill, rhs_fill);
let {bcx: bcx, val: new_vec_ptr} = alloc_raw(bcx, new_fill, new_fill);
new_vec_ptr = PointerCast(bcx, new_vec_ptr, T_ptr(T_vec(llunitty)));
new_vec_ptr = PointerCast(bcx, new_vec_ptr, T_ptr(T_vec(ccx, llunitty)));
let write_ptr_ptr = do_spill_noroot
(bcx, get_dataptr(bcx, new_vec_ptr, llunitty));
@ -232,13 +249,14 @@ fn trans_add(bcx: @block_ctxt, vec_ty: ty::t, lhs: ValueRef,
bind fn (bcx: @block_ctxt, addr: ValueRef, _ty: ty::t,
write_ptr_ptr: ValueRef, unit_ty: ty::t, llunitsz: ValueRef)
-> @block_ctxt {
let ccx = bcx_ccx(bcx);
let write_ptr = Load(bcx, write_ptr_ptr);
let bcx =
copy_val(bcx, INIT, write_ptr,
load_if_immediate(bcx, addr, unit_ty), unit_ty);
let incr =
ty::type_has_dynamic_size(bcx_tcx(bcx), unit_ty) ?
llunitsz : C_int(1);
llunitsz : C_int(ccx, 1);
Store(bcx, InBoundsGEP(bcx, write_ptr, [incr]),
write_ptr_ptr);
ret bcx;
@ -255,10 +273,11 @@ type iter_vec_block = block(@block_ctxt, ValueRef, ty::t) -> @block_ctxt;
fn iter_vec_raw(bcx: @block_ctxt, vptr: ValueRef, vec_ty: ty::t,
fill: ValueRef, f: iter_vec_block) -> @block_ctxt {
let ccx = bcx_ccx(bcx);
let unit_ty = ty::sequence_element_type(bcx_tcx(bcx), vec_ty);
let llunitty = type_of_or_i8(bcx, unit_ty);
let {bcx: bcx, val: unit_sz} = size_of(bcx, unit_ty);
vptr = PointerCast(bcx, vptr, T_ptr(T_vec(llunitty)));
vptr = PointerCast(bcx, vptr, T_ptr(T_vec(ccx, llunitty)));
let data_ptr = get_dataptr(bcx, vptr, llunitty);
// Calculate the last pointer address we want to handle.
@ -279,7 +298,7 @@ fn iter_vec_raw(bcx: @block_ctxt, vptr: ValueRef, vec_ty: ty::t,
let increment =
if ty::type_has_dynamic_size(bcx_tcx(bcx), unit_ty) {
unit_sz
} else { C_int(1) };
} else { C_int(ccx, 1) };
AddIncomingToPhi(data_ptr, InBoundsGEP(body_cx, data_ptr, [increment]),
body_cx.llbb);
Br(body_cx, header_cx.llbb);
@ -288,7 +307,8 @@ fn iter_vec_raw(bcx: @block_ctxt, vptr: ValueRef, vec_ty: ty::t,
fn iter_vec(bcx: @block_ctxt, vptr: ValueRef, vec_ty: ty::t,
f: iter_vec_block) -> @block_ctxt {
vptr = PointerCast(bcx, vptr, T_ptr(T_opaque_vec()));
let ccx = bcx_ccx(bcx);
vptr = PointerCast(bcx, vptr, T_ptr(ccx.opaque_vec_type));
ret iter_vec_raw(bcx, vptr, vec_ty, get_fill(bcx, vptr), f);
}