thread the context through so that int can be 64 bits on x86_64
This commit is contained in:
parent
2521cda1ec
commit
c0e9c42bd2
@ -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()),
|
||||
|
@ -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()));
|
||||
|
@ -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(),
|
||||
|
@ -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) {
|
||||
|
@ -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]);
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user