thread the context through so that int can be 64 bits on x86_64
This commit is contained in:
parent
2521cda1ec
commit
c0e9c42bd2
7 changed files with 149 additions and 99 deletions
|
@ -1,5 +1,6 @@
|
||||||
|
|
||||||
import std::str;
|
import std::str;
|
||||||
|
import driver::session;
|
||||||
import middle::trans;
|
import middle::trans;
|
||||||
import trans::decl_cdecl_fn;
|
import trans::decl_cdecl_fn;
|
||||||
import middle::trans_common::{T_f32, T_f64, T_fn, T_bool, T_i1, T_i8, T_i32,
|
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,
|
call_c_stack_float: ValueRef,
|
||||||
rust_personality: 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 {
|
llmod: ModuleRef) -> @upcalls {
|
||||||
fn decl(llmod: ModuleRef, name: str, tys: [TypeRef], rv: TypeRef) ->
|
fn decl(llmod: ModuleRef, name: str, tys: [TypeRef], rv: TypeRef) ->
|
||||||
ValueRef {
|
ValueRef {
|
||||||
|
@ -44,25 +47,35 @@ fn declare_upcalls(_tn: type_names, tydesc_type: TypeRef,
|
||||||
let d = bind decl(llmod, _, _, _);
|
let d = bind decl(llmod, _, _, _);
|
||||||
let dv = bind decl(llmod, _, _, T_void());
|
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:
|
malloc:
|
||||||
d("malloc", [T_size_t(), T_ptr(tydesc_type)], T_ptr(T_i8())),
|
d("malloc", [size_t, T_ptr(tydesc_type)],
|
||||||
free: dv("free", [T_ptr(T_i8()), T_int()]),
|
T_ptr(T_i8())),
|
||||||
|
free: dv("free", [T_ptr(T_i8()), int_t]),
|
||||||
shared_malloc:
|
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())),
|
T_ptr(T_i8())),
|
||||||
shared_free: dv("shared_free", [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:
|
get_type_desc:
|
||||||
d("get_type_desc",
|
d("get_type_desc",
|
||||||
[T_ptr(T_nil()), T_size_t(), T_size_t(), T_size_t(),
|
[T_ptr(T_nil()), size_t,
|
||||||
T_ptr(T_ptr(tydesc_type)), T_int()], T_ptr(tydesc_type)),
|
size_t, size_t,
|
||||||
|
T_ptr(T_ptr(tydesc_type)), int_t],
|
||||||
|
T_ptr(tydesc_type)),
|
||||||
vec_grow:
|
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:
|
vec_push:
|
||||||
dv("vec_push",
|
dv("vec_push",
|
||||||
[T_ptr(T_ptr(T_opaque_vec())), T_ptr(tydesc_type),
|
[T_ptr(T_ptr(opaque_vec_t)), T_ptr(tydesc_type),
|
||||||
T_ptr(T_i8())]),
|
T_ptr(T_i8())]),
|
||||||
cmp_type:
|
cmp_type:
|
||||||
dv("cmp_type",
|
dv("cmp_type",
|
||||||
[T_ptr(T_i1()), T_ptr(tydesc_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()]),
|
dv("log_type", [T_ptr(tydesc_type), T_ptr(T_i8()), T_i32()]),
|
||||||
dynastack_mark: d("dynastack_mark", [], T_ptr(T_i8())),
|
dynastack_mark: d("dynastack_mark", [], T_ptr(T_i8())),
|
||||||
dynastack_alloc:
|
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())),
|
T_ptr(T_i8())),
|
||||||
dynastack_free: dv("dynastack_free", [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())),
|
alloc_c_stack: d("alloc_c_stack", [T_size_t()], T_ptr(T_i8())),
|
||||||
call_c_stack: d("call_c_stack",
|
call_c_stack: d("call_c_stack",
|
||||||
[T_ptr(T_fn([], T_int())), T_ptr(T_i8())],
|
[T_ptr(T_fn([], T_int())), T_ptr(T_i8())],
|
||||||
T_int()),
|
int_t),
|
||||||
call_c_stack_i64: d("call_c_stack_i64",
|
call_c_stack_i64: d("call_c_stack_i64",
|
||||||
[T_ptr(T_fn([], T_int())), T_ptr(T_i8())],
|
[T_ptr(T_fn([], T_int())), T_ptr(T_i8())],
|
||||||
T_i64()),
|
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 {
|
fn add_gc_root(cx: @block_ctxt, llval: ValueRef, ty: ty::t) -> @block_ctxt {
|
||||||
let bcx = cx;
|
let bcx = cx;
|
||||||
|
let ccx = bcx_ccx(cx);
|
||||||
if !type_is_gc_relevant(bcx_tcx(cx), ty) ||
|
if !type_is_gc_relevant(bcx_tcx(cx), ty) ||
|
||||||
ty::type_has_dynamic_size(bcx_tcx(cx), ty) {
|
ty::type_has_dynamic_size(bcx_tcx(cx), ty) {
|
||||||
ret bcx;
|
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;
|
gc_cx.next_tydesc_num += 1u;
|
||||||
|
|
||||||
let lldestindex =
|
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");
|
"rust_gc_tydesc_dest_index");
|
||||||
let llsrcindex =
|
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");
|
"rust_gc_tydesc_src_index");
|
||||||
|
|
||||||
lldestindex = lll::LLVMConstPointerCast(lldestindex, T_ptr(T_i8()));
|
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.
|
// Static type descriptor.
|
||||||
|
|
||||||
let llstaticgcmeta =
|
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");
|
"rust_gc_tydesc_static_gc_meta");
|
||||||
let llstaticgcmetaptr =
|
let llstaticgcmetaptr =
|
||||||
lll::LLVMConstPointerCast(llstaticgcmeta, T_ptr(T_i8()));
|
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) {
|
ty::ty_vec(mt) {
|
||||||
let mt_ty = mt.ty;
|
let mt_ty = mt.ty;
|
||||||
if ty::type_has_dynamic_size(cx.tcx, 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 {
|
} else {
|
||||||
// should be unnecessary
|
// should be unnecessary
|
||||||
check non_ty_var(cx, mt_ty);
|
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);
|
get_simple_extern_fn(cx, externs, llmod, name, n);
|
||||||
let call_args: [ValueRef] = [];
|
let call_args: [ValueRef] = [];
|
||||||
for a: ValueRef in args {
|
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);
|
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 next_cx = new_sub_block_ctxt(cx, "next");
|
||||||
let seq_ty = ty::expr_ty(bcx_tcx(cx), seq);
|
let seq_ty = ty::expr_ty(bcx_tcx(cx), seq);
|
||||||
let {bcx: bcx, val: seq} = trans_temp_expr(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);
|
let fill = tvec::get_fill(bcx, seq);
|
||||||
if ty::type_is_str(bcx_tcx(bcx), seq_ty) {
|
if ty::type_is_str(bcx_tcx(bcx), seq_ty) {
|
||||||
fill = Sub(bcx, fill, C_int(ccx, 1));
|
fill = Sub(bcx, fill, C_int(ccx, 1));
|
||||||
|
@ -6075,7 +6075,7 @@ fn fill_crate_map(ccx: @crate_ctxt, map: ValueRef) {
|
||||||
llvm::LLVMSetLinkage(map,
|
llvm::LLVMSetLinkage(map,
|
||||||
lib::llvm::LLVMExternalLinkage as llvm::Linkage);
|
lib::llvm::LLVMExternalLinkage as llvm::Linkage);
|
||||||
llvm::LLVMSetInitializer(map,
|
llvm::LLVMSetInitializer(map,
|
||||||
C_struct([p2i(create_module_map(ccx)),
|
C_struct([p2i(ccx, create_module_map(ccx)),
|
||||||
C_array(ccx.int_type, subcrates)]));
|
C_array(ccx.int_type, subcrates)]));
|
||||||
ret map;
|
ret map;
|
||||||
>>>>>>> work on making the size of ints depend on the target arch
|
>>>>>>> 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 _: () =
|
let _: () =
|
||||||
str::as_buf(sess.get_targ_cfg().target_strs.target_triple,
|
str::as_buf(sess.get_targ_cfg().target_strs.target_triple,
|
||||||
{|buf| llvm::LLVMSetTarget(llmod, buf) });
|
{|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 td = mk_target_data(sess.get_targ_cfg().target_strs.data_layout);
|
||||||
let tn = mk_type_names();
|
let tn = mk_type_names();
|
||||||
let intrinsics = declare_intrinsics(llmod);
|
let intrinsics = declare_intrinsics(llmod);
|
||||||
let int_type = T_int(sess.get_targ_cfg().arch);
|
let int_type = T_int(targ_cfg);
|
||||||
let float_type = T_float(sess.get_targ_cfg().arch);
|
let float_type = T_float(targ_cfg);
|
||||||
let task_type = T_task(sess.get_targ_cfg().arch);
|
let task_type = T_task(targ_cfg);
|
||||||
let taskptr_type = T_ptr(task_type);
|
let taskptr_type = T_ptr(task_type);
|
||||||
tn.associate("taskptr", taskptr_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);
|
tn.associate("tydesc", tydesc_type);
|
||||||
let hasher = ty::hash_ty;
|
let hasher = ty::hash_ty;
|
||||||
let eqer = ty::eq_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,
|
mutable n_real_glues: 0u,
|
||||||
fn_times: @mutable []},
|
fn_times: @mutable []},
|
||||||
upcalls:
|
upcalls:
|
||||||
upcall::declare_upcalls(tn, tydesc_type, llmod),
|
upcall::declare_upcalls(targ_cfg, tn, tydesc_type,
|
||||||
|
llmod),
|
||||||
rust_object_type: T_rust_object(),
|
rust_object_type: T_rust_object(),
|
||||||
tydesc_type: tydesc_type,
|
tydesc_type: tydesc_type,
|
||||||
int_type: int_type,
|
int_type: int_type,
|
||||||
float_type: float_type,
|
float_type: float_type,
|
||||||
task_type: task_type,
|
task_type: task_type,
|
||||||
|
opaque_vec_type: T_opaque_vec(targ_cfg),
|
||||||
builder: BuilderRef_res(llvm::LLVMCreateBuilder()),
|
builder: BuilderRef_res(llvm::LLVMCreateBuilder()),
|
||||||
shape_cx: shape::mk_ctxt(llmod),
|
shape_cx: shape::mk_ctxt(llmod),
|
||||||
gc_cx: gc::mk_ctxt(),
|
gc_cx: gc::mk_ctxt(),
|
||||||
|
|
|
@ -44,6 +44,7 @@ tag opt_result {
|
||||||
range_result(result, result);
|
range_result(result, result);
|
||||||
}
|
}
|
||||||
fn trans_opt(bcx: @block_ctxt, o: opt) -> opt_result {
|
fn trans_opt(bcx: @block_ctxt, o: opt) -> opt_result {
|
||||||
|
let ccx = bcx_ccx(bcx);
|
||||||
alt o {
|
alt o {
|
||||||
lit(l) {
|
lit(l) {
|
||||||
alt l.node {
|
alt l.node {
|
||||||
|
@ -56,11 +57,11 @@ fn trans_opt(bcx: @block_ctxt, o: opt) -> opt_result {
|
||||||
}
|
}
|
||||||
_ {
|
_ {
|
||||||
ret single_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) {
|
range(l1, l2) {
|
||||||
let cell1 = trans::empty_dest_cell();
|
let cell1 = trans::empty_dest_cell();
|
||||||
let cell2 = 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);
|
vec::len(ty::tag_variant_with_id(ccx.tcx, vdefs.tg, vdefs.var).args);
|
||||||
if size > 0u && vec::len(variants) != 1u {
|
if size > 0u && vec::len(variants) != 1u {
|
||||||
let tagptr =
|
let tagptr =
|
||||||
PointerCast(bcx, val, trans_common::T_opaque_tag_ptr(ccx.tn));
|
PointerCast(bcx, val, trans_common::T_opaque_tag_ptr(ccx));
|
||||||
blobptr = GEP(bcx, tagptr, [C_int(0), C_int(1)]);
|
blobptr = GEP(bcx, tagptr, [C_int(ccx, 0), C_int(ccx, 1)]);
|
||||||
}
|
}
|
||||||
let i = 0u;
|
let i = 0u;
|
||||||
let vdefs_tg = vdefs.tg;
|
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 box = Load(bcx, val);
|
||||||
let unboxed =
|
let unboxed =
|
||||||
InBoundsGEP(bcx, box,
|
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,
|
compile_submatch(bcx, enter_box(m, col, val), [unboxed] + vals_left,
|
||||||
f, exits);
|
f, exits);
|
||||||
ret;
|
ret;
|
||||||
|
@ -465,8 +467,9 @@ fn compile_submatch(bcx: @block_ctxt, m: match, vals: [ValueRef], f: mk_fail,
|
||||||
} else {
|
} else {
|
||||||
let tagptr =
|
let tagptr =
|
||||||
PointerCast(bcx, val,
|
PointerCast(bcx, val,
|
||||||
trans_common::T_opaque_tag_ptr(ccx.tn));
|
trans_common::T_opaque_tag_ptr(ccx));
|
||||||
let discrimptr = GEP(bcx, tagptr, [C_int(0), C_int(0)]);
|
let discrimptr = GEP(bcx, tagptr, [C_int(ccx, 0),
|
||||||
|
C_int(ccx, 0)]);
|
||||||
test_val = Load(bcx, discrimptr);
|
test_val = Load(bcx, discrimptr);
|
||||||
kind = switch;
|
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).
|
// holding a corrupted value (when the compiler is optimized).
|
||||||
// This can be removed after our next LLVM upgrade.
|
// This can be removed after our next LLVM upgrade.
|
||||||
val_ty(sw);
|
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
|
// Compile subtrees for each option
|
||||||
for opt: opt in opts {
|
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 box = Load(bcx, val);
|
||||||
let unboxed =
|
let unboxed =
|
||||||
InBoundsGEP(bcx, box,
|
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);
|
bcx = bind_irrefutable_pat(bcx, inner, unboxed, true);
|
||||||
}
|
}
|
||||||
ast::pat_uniq(inner) {
|
ast::pat_uniq(inner) {
|
||||||
|
|
|
@ -123,6 +123,7 @@ type crate_ctxt =
|
||||||
int_type: TypeRef,
|
int_type: TypeRef,
|
||||||
float_type: TypeRef,
|
float_type: TypeRef,
|
||||||
task_type: TypeRef,
|
task_type: TypeRef,
|
||||||
|
opaque_vec_type: TypeRef,
|
||||||
builder: BuilderRef_res,
|
builder: BuilderRef_res,
|
||||||
shape_cx: shape::ctxt,
|
shape_cx: shape::ctxt,
|
||||||
gc_cx: gc::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_bool() -> TypeRef { ret T_i1(); }
|
||||||
|
|
||||||
fn T_int(arch: session::arch) -> TypeRef {
|
fn T_int(targ_cfg: @session::config) -> TypeRef {
|
||||||
ret alt arch {
|
ret alt targ_cfg.arch {
|
||||||
arch_x86 { T_i32() }
|
session::arch_x86. { T_i32() }
|
||||||
arch_x86_64 { T_i64() }
|
session::arch_x86_64. { T_i64() }
|
||||||
arch_arm { T_i32() }
|
session::arch_arm. { T_i32() }
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
fn T_float(arch: session::arch) -> TypeRef {
|
fn T_float(targ_cfg: @session::config) -> TypeRef {
|
||||||
ret alt arch {
|
ret alt targ_cfg.arch {
|
||||||
arch_x86 { T_f64() }
|
session::arch_x86. { T_f64() }
|
||||||
arch_x86_64 { T_f64() }
|
session::arch_x86_64. { T_f64() }
|
||||||
arch_arm { T_f64() }
|
session::arch_arm. { T_f64() }
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
fn T_char() -> TypeRef { ret T_i32(); }
|
fn T_char() -> TypeRef { ret T_i32(); }
|
||||||
|
|
||||||
fn T_size_t(cx: @crate_ctxt) -> TypeRef {
|
fn T_size_t(targ_cfg: @session::config) -> TypeRef {
|
||||||
ret cx.int_type;
|
ret T_int(targ_cfg);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn T_fn(inputs: [TypeRef], output: TypeRef) -> TypeRef {
|
fn T_fn(inputs: [TypeRef], output: TypeRef) -> TypeRef {
|
||||||
|
@ -553,7 +554,7 @@ fn T_rust_object() -> TypeRef {
|
||||||
ret t;
|
ret t;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn T_task(arch: session::arch) -> TypeRef {
|
fn T_task(targ_cfg: @session::config) -> TypeRef {
|
||||||
let t = T_named_struct("task");
|
let t = T_named_struct("task");
|
||||||
|
|
||||||
// Refcount
|
// Refcount
|
||||||
|
@ -567,7 +568,7 @@ fn T_task(arch: session::arch) -> TypeRef {
|
||||||
// Domain pointer
|
// Domain pointer
|
||||||
// Crate cache pointer
|
// Crate cache pointer
|
||||||
|
|
||||||
let t_int = T_int(arch);
|
let t_int = T_int(targ_cfg);
|
||||||
let elems =
|
let elems =
|
||||||
[t_int, t_int, t_int, t_int,
|
[t_int, t_int, t_int, t_int,
|
||||||
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;
|
ret t;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn T_tydesc(cx: @crate_ctxt) -> TypeRef {
|
fn T_tydesc(targ_cfg: @session::config) -> TypeRef {
|
||||||
let tydesc = T_named_struct("tydesc");
|
let tydesc = T_named_struct("tydesc");
|
||||||
let tydescpp = T_ptr(T_ptr(tydesc));
|
let tydescpp = T_ptr(T_ptr(tydesc));
|
||||||
let pvoid = T_ptr(T_i8());
|
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,
|
T_ptr(T_fn([T_ptr(T_i1()), T_ptr(tydesc), tydescpp,
|
||||||
pvoid, pvoid, T_i8()], T_void()));
|
pvoid, pvoid, T_i8()], T_void()));
|
||||||
|
|
||||||
|
let int_type = T_int(targ_cfg);
|
||||||
let elems =
|
let elems =
|
||||||
[tydescpp, cx.int_type, cx.int_type,
|
[tydescpp, int_type, int_type,
|
||||||
glue_fn_ty, glue_fn_ty, glue_fn_ty,
|
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()), 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);
|
set_struct_body(tydesc, elems);
|
||||||
ret tydesc;
|
ret tydesc;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn T_array(t: TypeRef, n: uint) -> TypeRef { ret llvm::LLVMArrayType(t, n); }
|
fn T_array(t: TypeRef, n: uint) -> TypeRef { ret llvm::LLVMArrayType(t, n); }
|
||||||
|
|
||||||
|
|
||||||
// Interior vector.
|
// Interior vector.
|
||||||
//
|
//
|
||||||
// TODO: Support user-defined vector sizes.
|
// TODO: Support user-defined vector sizes.
|
||||||
fn T_vec(cx: @crate_ctxt, t: TypeRef) -> TypeRef {
|
fn T_vec2(targ_cfg: @session::config, t: TypeRef) -> TypeRef {
|
||||||
ret T_struct([cx.int_type, // fill
|
ret T_struct([T_int(targ_cfg), // fill
|
||||||
cx.int_type, // alloc
|
T_int(targ_cfg), // alloc
|
||||||
T_array(t, 0u)]); // elements
|
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.
|
// 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 {
|
fn T_box(cx: @crate_ctxt, t: TypeRef) -> TypeRef {
|
||||||
ret T_struct([cx.int_type, t]);
|
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.
|
// 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
|
// abi::obj_field_vtbl and abi::obj_field_box simply specify words 0 and 1
|
||||||
// of 'pair'.
|
// of 'pair'.
|
||||||
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]);
|
||||||
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]);
|
||||||
|
|
||||||
// Make a vtable for this object: a static array of pointers to functions.
|
// 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
|
// 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);
|
box = PointerCast(bcx, box, llbox_ty);
|
||||||
}
|
}
|
||||||
let pair = trans::get_dest_addr(dest);
|
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);
|
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);
|
Store(bcx, box, pair_box);
|
||||||
ret bcx;
|
ret bcx;
|
||||||
}
|
}
|
||||||
|
@ -627,7 +627,7 @@ fn process_bkwding_mthd(cx: @local_ctxt, sp: span, m: @ty::method,
|
||||||
PointerCast(bcx, fcx.llenv,
|
PointerCast(bcx, fcx.llenv,
|
||||||
T_ptr(T_struct([cx.ccx.rust_object_type,
|
T_ptr(T_struct([cx.ccx.rust_object_type,
|
||||||
T_ptr(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);
|
llself_obj_ptr = Load(bcx, llself_obj_ptr);
|
||||||
|
|
||||||
// Cast it back to pointer-to-object-type, so LLVM won't complain.
|
// 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 vtbl_type = T_ptr(T_array(T_ptr(T_nil()), ix + 1u));
|
||||||
|
|
||||||
let llouter_obj_vtbl =
|
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 = Load(bcx, llouter_obj_vtbl);
|
||||||
llouter_obj_vtbl = PointerCast(bcx, llouter_obj_vtbl, vtbl_type);
|
llouter_obj_vtbl = PointerCast(bcx, llouter_obj_vtbl, vtbl_type);
|
||||||
|
|
||||||
let llouter_mthd =
|
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.
|
// Set up the outer method to be called.
|
||||||
let llouter_mthd_ty = type_of_meth(bcx_ccx(bcx), sp, m, ty_params);
|
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
|
// First, grab the box out of the self_obj. It contains a refcount and a
|
||||||
// body.
|
// body.
|
||||||
let llself_obj_box =
|
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);
|
llself_obj_box = Load(bcx, llself_obj_box);
|
||||||
|
|
||||||
let ccx = bcx_ccx(bcx);
|
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);
|
llself_obj_box = PointerCast(bcx, llself_obj_box, llbox_ty);
|
||||||
|
|
||||||
// Now, reach into the box and grab the body.
|
// Now, reach into the box and grab the body.
|
||||||
let llself_obj_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
|
// Now, we need to figure out exactly what type the body is supposed to be
|
||||||
// cast to.
|
// 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
|
// method's entry out of the vtable so that the forwarding function can
|
||||||
// call it.
|
// call it.
|
||||||
let llinner_obj_vtbl =
|
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);
|
llinner_obj_vtbl = Load(bcx, llinner_obj_vtbl);
|
||||||
|
|
||||||
let llinner_obj_body =
|
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);
|
llinner_obj_body = Load(bcx, llinner_obj_body);
|
||||||
|
|
||||||
// Get the index of the method we want.
|
// 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);
|
llinner_obj_vtbl = PointerCast(bcx, llinner_obj_vtbl, vtbl_type);
|
||||||
|
|
||||||
let llorig_mthd =
|
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.
|
// Set up the original method to be called.
|
||||||
let llorig_mthd_ty = type_of_meth(bcx_ccx(bcx), sp, m, ty_params);
|
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 {
|
inner_obj_body: ValueRef) -> ValueRef {
|
||||||
|
|
||||||
// Drop the outer obj into the second slot.
|
// 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);
|
Store(bcx, outer_obj, self_pair_ptr);
|
||||||
|
|
||||||
// Drop in the backwarding vtbl.
|
// Drop in the backwarding vtbl.
|
||||||
let wrapper_pair = GEP(bcx, self_stack, [C_int(0), C_int(0)]);
|
let wrapper_pair = GEPi(bcx, self_stack, [0, 0]);
|
||||||
let wrapper_vtbl_ptr = GEP(bcx, wrapper_pair, [C_int(0), C_int(0)]);
|
let wrapper_vtbl_ptr = GEPi(bcx, wrapper_pair, [0, 0]);
|
||||||
let backwarding_vtbl_cast =
|
let backwarding_vtbl_cast =
|
||||||
PointerCast(bcx, backwarding_vtbl, T_ptr(T_empty_struct()));
|
PointerCast(bcx, backwarding_vtbl, T_ptr(T_empty_struct()));
|
||||||
Store(bcx, backwarding_vtbl_cast, wrapper_vtbl_ptr);
|
Store(bcx, backwarding_vtbl_cast, wrapper_vtbl_ptr);
|
||||||
|
|
||||||
// Drop in the inner obj body.
|
// 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);
|
Store(bcx, inner_obj_body, wrapper_body_ptr);
|
||||||
|
|
||||||
ret self_stack;
|
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 {
|
fn alloc_raw(bcx: @block_ctxt, fill: ValueRef, alloc: ValueRef) -> result {
|
||||||
let llvecty = T_opaque_vec();
|
let ccx = bcx_ccx(bcx);
|
||||||
let vecsize = Add(bcx, alloc, llsize_of(llvecty));
|
let llvecty = ccx.opaque_vec_type;
|
||||||
|
let vecsize = Add(bcx, alloc, llsize_of(ccx, llvecty));
|
||||||
let {bcx: bcx, val: vecptr} =
|
let {bcx: bcx, val: vecptr} =
|
||||||
trans_shared_malloc(bcx, T_ptr(llvecty), vecsize);
|
trans_shared_malloc(bcx, T_ptr(llvecty), vecsize);
|
||||||
Store(bcx, fill,
|
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,
|
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};
|
ret {bcx: bcx, val: vecptr};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -47,13 +50,18 @@ type alloc_result =
|
||||||
llunitty: TypeRef};
|
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) -> alloc_result {
|
||||||
|
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(bcx, unit_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 {bcx: bcx, val: unit_sz} = size_of(bcx, unit_ty);
|
||||||
|
|
||||||
let fill = Mul(bcx, C_uint(elts), unit_sz);
|
let fill = Mul(bcx, C_uint(ccx, elts), unit_sz);
|
||||||
let alloc = if elts < 4u { Mul(bcx, C_int(4), unit_sz) } else { fill };
|
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 {bcx: bcx, val: vptr} = alloc_raw(bcx, fill, alloc);
|
||||||
let vptr = PointerCast(bcx, vptr, T_ptr(llvecty));
|
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 {
|
fn duplicate(bcx: @block_ctxt, vptr: ValueRef, vec_ty: ty::t) -> result {
|
||||||
|
let ccx = bcx_ccx(bcx);
|
||||||
let fill = get_fill(bcx, vptr);
|
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} =
|
let {bcx: bcx, val: newptr} =
|
||||||
trans_shared_malloc(bcx, val_ty(vptr), size);
|
trans_shared_malloc(bcx, val_ty(vptr), size);
|
||||||
let bcx = call_memmove(bcx, newptr, vptr, size).bcx;
|
let bcx = call_memmove(bcx, newptr, vptr, size).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);
|
||||||
Store(bcx, fill,
|
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) {
|
if ty::type_needs_drop(bcx_tcx(bcx), unit_ty) {
|
||||||
bcx = iter_vec(bcx, newptr, vec_ty, trans::take_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,
|
fn trans_vec(bcx: @block_ctxt, args: [@ast::expr], id: ast::node_id,
|
||||||
dest: dest) -> @block_ctxt {
|
dest: dest) -> @block_ctxt {
|
||||||
|
let ccx = bcx_ccx(bcx);
|
||||||
if dest == trans::ignore {
|
if dest == trans::ignore {
|
||||||
for arg in args {
|
for arg in args {
|
||||||
bcx = trans::trans_expr(bcx, arg, trans::ignore);
|
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];
|
let i = 0u, temp_cleanups = [vptr];
|
||||||
for e in args {
|
for e in args {
|
||||||
let lleltptr = if ty::type_has_dynamic_size(bcx_tcx(bcx), unit_ty) {
|
let lleltptr = if ty::type_has_dynamic_size(bcx_tcx(bcx), unit_ty) {
|
||||||
InBoundsGEP(bcx, dataptr, [Mul(bcx, C_uint(i), llunitsz)])
|
InBoundsGEP(bcx, dataptr, [Mul(bcx, C_uint(ccx, i), llunitsz)])
|
||||||
} else { InBoundsGEP(bcx, dataptr, [C_uint(i)]) };
|
} else { InBoundsGEP(bcx, dataptr, [C_uint(ccx, i)]) };
|
||||||
bcx = trans::trans_expr_save_in(bcx, e, lleltptr);
|
bcx = trans::trans_expr_save_in(bcx, e, lleltptr);
|
||||||
add_clean_temp_mem(bcx, lleltptr, unit_ty);
|
add_clean_temp_mem(bcx, lleltptr, unit_ty);
|
||||||
temp_cleanups += [lleltptr];
|
temp_cleanups += [lleltptr];
|
||||||
|
@ -131,21 +142,23 @@ fn trans_str(bcx: @block_ctxt, s: str, dest: dest) -> @block_ctxt {
|
||||||
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);
|
||||||
|
|
||||||
let llcstr = C_cstr(bcx_ccx(bcx), s);
|
let ccx = bcx_ccx(bcx);
|
||||||
|
let llcstr = C_cstr(ccx, s);
|
||||||
let bcx =
|
let bcx =
|
||||||
call_memmove(bcx, get_dataptr(bcx, sptr, T_i8()), llcstr,
|
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);
|
ret trans::store_in_dest(bcx, sptr, dest);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn trans_append(cx: @block_ctxt, vec_ty: ty::t, lhsptr: ValueRef,
|
fn trans_append(cx: @block_ctxt, vec_ty: ty::t, lhsptr: ValueRef,
|
||||||
rhs: ValueRef) -> @block_ctxt {
|
rhs: ValueRef) -> @block_ctxt {
|
||||||
// Cast to opaque interior vector types if necessary.
|
// 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 unit_ty = ty::sequence_element_type(bcx_tcx(cx), vec_ty);
|
||||||
let dynamic = ty::type_has_dynamic_size(bcx_tcx(cx), unit_ty);
|
let dynamic = ty::type_has_dynamic_size(bcx_tcx(cx), unit_ty);
|
||||||
if dynamic {
|
if dynamic {
|
||||||
lhsptr = PointerCast(cx, lhsptr, T_ptr(T_ptr(T_opaque_vec())));
|
lhsptr = PointerCast(cx, lhsptr, T_ptr(T_ptr(ccx.opaque_vec_type)));
|
||||||
rhs = PointerCast(cx, rhs, T_ptr(T_opaque_vec()));
|
rhs = PointerCast(cx, rhs, T_ptr(ccx.opaque_vec_type));
|
||||||
}
|
}
|
||||||
let strings = alt ty::struct(bcx_tcx(cx), vec_ty) {
|
let strings = alt ty::struct(bcx_tcx(cx), vec_ty) {
|
||||||
ty::ty_str. { true }
|
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 lfill = get_fill(bcx, lhs);
|
||||||
let rfill = get_fill(bcx, rhs);
|
let rfill = get_fill(bcx, rhs);
|
||||||
let new_fill = Add(bcx, lfill, rfill);
|
let new_fill = Add(bcx, lfill, rfill);
|
||||||
if strings { new_fill = Sub(bcx, new_fill, C_int(1)); }
|
if strings { new_fill = Sub(bcx, new_fill, C_int(ccx, 1)); }
|
||||||
let opaque_lhs = PointerCast(bcx, lhsptr, T_ptr(T_ptr(T_opaque_vec())));
|
let opaque_lhs = PointerCast(bcx, lhsptr,
|
||||||
|
T_ptr(T_ptr(ccx.opaque_vec_type)));
|
||||||
Call(bcx, bcx_ccx(cx).upcalls.vec_grow,
|
Call(bcx, bcx_ccx(cx).upcalls.vec_grow,
|
||||||
[opaque_lhs, new_fill]);
|
[opaque_lhs, new_fill]);
|
||||||
// Was overwritten if we resized
|
// 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_data = get_dataptr(bcx, lhs, llunitty);
|
||||||
let lhs_off = lfill;
|
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 = pointer_add(bcx, lhs_data, lhs_off);
|
||||||
let write_ptr_ptr = do_spill_noroot(bcx, write_ptr);
|
let write_ptr_ptr = do_spill_noroot(bcx, write_ptr);
|
||||||
let bcx = iter_vec_raw(bcx, rhs, vec_ty, rfill,
|
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,
|
copy_val(bcx, INIT, write_ptr,
|
||||||
load_if_immediate(bcx, addr, unit_ty),
|
load_if_immediate(bcx, addr, unit_ty),
|
||||||
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]),
|
Store(bcx, InBoundsGEP(bcx, write_ptr, [incr]),
|
||||||
write_ptr_ptr);
|
write_ptr_ptr);
|
||||||
ret bcx;
|
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,
|
fn trans_append_literal(bcx: @block_ctxt, vptrptr: ValueRef, vec_ty: ty::t,
|
||||||
vals: [@ast::expr]) -> @block_ctxt {
|
vals: [@ast::expr]) -> @block_ctxt {
|
||||||
|
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;
|
||||||
let {bcx: bcx, val: td} =
|
let {bcx: bcx, val: td} =
|
||||||
get_tydesc(bcx, elt_ty, false, tps_normal, ti).result;
|
get_tydesc(bcx, elt_ty, false, tps_normal, ti).result;
|
||||||
trans::lazily_emit_tydesc_glue(bcx, abi::tydesc_field_take_glue, ti);
|
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 {
|
for val in vals {
|
||||||
let {bcx: e_bcx, val: elt} = trans::trans_temp_expr(bcx, val);
|
let {bcx: e_bcx, val: elt} = trans::trans_temp_expr(bcx, val);
|
||||||
bcx = e_bcx;
|
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,
|
fn trans_add(bcx: @block_ctxt, vec_ty: ty::t, lhs: ValueRef,
|
||||||
rhs: ValueRef, dest: dest) -> @block_ctxt {
|
rhs: ValueRef, dest: dest) -> @block_ctxt {
|
||||||
|
let ccx = bcx_ccx(bcx);
|
||||||
let strings = alt ty::struct(bcx_tcx(bcx), vec_ty) {
|
let strings = alt ty::struct(bcx_tcx(bcx), vec_ty) {
|
||||||
ty::ty_str. { true }
|
ty::ty_str. { true }
|
||||||
ty::ty_vec(_) { false }
|
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 {bcx: bcx, val: llunitsz} = size_of(bcx, unit_ty);
|
||||||
|
|
||||||
let lhs_fill = get_fill(bcx, lhs);
|
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 rhs_fill = get_fill(bcx, rhs);
|
||||||
let new_fill = Add(bcx, lhs_fill, rhs_fill);
|
let new_fill = Add(bcx, lhs_fill, rhs_fill);
|
||||||
let {bcx: bcx, val: new_vec_ptr} = alloc_raw(bcx, new_fill, new_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
|
let write_ptr_ptr = do_spill_noroot
|
||||||
(bcx, get_dataptr(bcx, new_vec_ptr, llunitty));
|
(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,
|
bind fn (bcx: @block_ctxt, addr: ValueRef, _ty: ty::t,
|
||||||
write_ptr_ptr: ValueRef, unit_ty: ty::t, llunitsz: ValueRef)
|
write_ptr_ptr: ValueRef, unit_ty: ty::t, llunitsz: ValueRef)
|
||||||
-> @block_ctxt {
|
-> @block_ctxt {
|
||||||
|
let ccx = bcx_ccx(bcx);
|
||||||
let write_ptr = Load(bcx, write_ptr_ptr);
|
let write_ptr = Load(bcx, write_ptr_ptr);
|
||||||
let bcx =
|
let bcx =
|
||||||
copy_val(bcx, INIT, write_ptr,
|
copy_val(bcx, INIT, write_ptr,
|
||||||
load_if_immediate(bcx, addr, unit_ty), unit_ty);
|
load_if_immediate(bcx, addr, unit_ty), unit_ty);
|
||||||
let incr =
|
let incr =
|
||||||
ty::type_has_dynamic_size(bcx_tcx(bcx), unit_ty) ?
|
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]),
|
Store(bcx, InBoundsGEP(bcx, write_ptr, [incr]),
|
||||||
write_ptr_ptr);
|
write_ptr_ptr);
|
||||||
ret bcx;
|
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,
|
fn iter_vec_raw(bcx: @block_ctxt, vptr: ValueRef, vec_ty: ty::t,
|
||||||
fill: ValueRef, f: iter_vec_block) -> @block_ctxt {
|
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 unit_ty = ty::sequence_element_type(bcx_tcx(bcx), vec_ty);
|
||||||
let llunitty = type_of_or_i8(bcx, unit_ty);
|
let llunitty = type_of_or_i8(bcx, unit_ty);
|
||||||
let {bcx: bcx, val: unit_sz} = size_of(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);
|
let data_ptr = get_dataptr(bcx, vptr, llunitty);
|
||||||
|
|
||||||
// Calculate the last pointer address we want to handle.
|
// 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 =
|
let increment =
|
||||||
if ty::type_has_dynamic_size(bcx_tcx(bcx), unit_ty) {
|
if ty::type_has_dynamic_size(bcx_tcx(bcx), unit_ty) {
|
||||||
unit_sz
|
unit_sz
|
||||||
} else { C_int(1) };
|
} else { C_int(ccx, 1) };
|
||||||
AddIncomingToPhi(data_ptr, InBoundsGEP(body_cx, data_ptr, [increment]),
|
AddIncomingToPhi(data_ptr, InBoundsGEP(body_cx, data_ptr, [increment]),
|
||||||
body_cx.llbb);
|
body_cx.llbb);
|
||||||
Br(body_cx, header_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,
|
fn iter_vec(bcx: @block_ctxt, vptr: ValueRef, vec_ty: ty::t,
|
||||||
f: iter_vec_block) -> @block_ctxt {
|
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);
|
ret iter_vec_raw(bcx, vptr, vec_ty, get_fill(bcx, vptr), f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue