Majority of the remaining work for derived tydescs. Not quite working yet.
This commit is contained in:
parent
21418230cd
commit
784b2decf2
@ -63,6 +63,7 @@ type tag_info = rec(type_handle th,
|
|||||||
state type crate_ctxt = rec(session.session sess,
|
state type crate_ctxt = rec(session.session sess,
|
||||||
ModuleRef llmod,
|
ModuleRef llmod,
|
||||||
target_data td,
|
target_data td,
|
||||||
|
ValueRef crate_ptr,
|
||||||
hashmap[str, ValueRef] upcalls,
|
hashmap[str, ValueRef] upcalls,
|
||||||
hashmap[str, ValueRef] intrinsics,
|
hashmap[str, ValueRef] intrinsics,
|
||||||
hashmap[str, ValueRef] item_names,
|
hashmap[str, ValueRef] item_names,
|
||||||
@ -687,25 +688,25 @@ fn llalign_of(TypeRef t) -> ValueRef {
|
|||||||
ret llvm.LLVMConstIntCast(lib.llvm.llvm.LLVMAlignOf(t), T_int(), False);
|
ret llvm.LLVMConstIntCast(lib.llvm.llvm.LLVMAlignOf(t), T_int(), False);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn size_of(@block_ctxt cx, @ty.t t) -> ValueRef {
|
fn size_of(@block_ctxt cx, @ty.t t) -> result {
|
||||||
if (!ty.type_has_dynamic_size(t)) {
|
if (!ty.type_has_dynamic_size(t)) {
|
||||||
ret llsize_of(type_of(cx.fcx.ccx, t));
|
ret res(cx, llsize_of(type_of(cx.fcx.ccx, t)));
|
||||||
}
|
}
|
||||||
ret dynamic_size_of(cx, t);
|
ret dynamic_size_of(cx, t);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn align_of(@block_ctxt cx, @ty.t t) -> ValueRef {
|
fn align_of(@block_ctxt cx, @ty.t t) -> result {
|
||||||
if (!ty.type_has_dynamic_size(t)) {
|
if (!ty.type_has_dynamic_size(t)) {
|
||||||
ret llalign_of(type_of(cx.fcx.ccx, t));
|
ret res(cx, llalign_of(type_of(cx.fcx.ccx, t)));
|
||||||
}
|
}
|
||||||
ret dynamic_align_of(cx, t);
|
ret dynamic_align_of(cx, t);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn dynamic_size_of(@block_ctxt cx, @ty.t t) -> ValueRef {
|
fn dynamic_size_of(@block_ctxt cx, @ty.t t) -> result {
|
||||||
alt (t.struct) {
|
alt (t.struct) {
|
||||||
case (ty.ty_param(?p)) {
|
case (ty.ty_param(?p)) {
|
||||||
auto szptr = field_of_tydesc(cx, t, abi.tydesc_field_size);
|
auto szptr = field_of_tydesc(cx, t, abi.tydesc_field_size);
|
||||||
ret cx.build.Load(szptr);
|
ret res(szptr.bcx, szptr.bcx.build.Load(szptr.val));
|
||||||
}
|
}
|
||||||
case (ty.ty_tup(?elts)) {
|
case (ty.ty_tup(?elts)) {
|
||||||
//
|
//
|
||||||
@ -718,51 +719,63 @@ fn dynamic_size_of(@block_ctxt cx, @ty.t t) -> ValueRef {
|
|||||||
//
|
//
|
||||||
auto off = C_int(0);
|
auto off = C_int(0);
|
||||||
auto max_align = C_int(1);
|
auto max_align = C_int(1);
|
||||||
|
auto bcx = cx;
|
||||||
for (@ty.t e in elts) {
|
for (@ty.t e in elts) {
|
||||||
auto elt_align = align_of(cx, e);
|
auto elt_align = align_of(bcx, e);
|
||||||
auto elt_size = size_of(cx, e);
|
bcx = elt_align.bcx;
|
||||||
auto aligned_off = align_to(cx, off, elt_align);
|
auto elt_size = size_of(bcx, e);
|
||||||
off = cx.build.Add(aligned_off, elt_size);
|
bcx = elt_size.bcx;
|
||||||
max_align = umax(cx, max_align, elt_align);
|
auto aligned_off = align_to(bcx, off, elt_align.val);
|
||||||
|
off = cx.build.Add(aligned_off, elt_size.val);
|
||||||
|
max_align = umax(bcx, max_align, elt_align.val);
|
||||||
}
|
}
|
||||||
off = align_to(cx, off, max_align);
|
off = align_to(bcx, off, max_align);
|
||||||
ret off;
|
ret res(bcx, off);
|
||||||
}
|
}
|
||||||
case (ty.ty_rec(?flds)) {
|
case (ty.ty_rec(?flds)) {
|
||||||
auto off = C_int(0);
|
auto off = C_int(0);
|
||||||
auto max_align = C_int(1);
|
auto max_align = C_int(1);
|
||||||
|
auto bcx = cx;
|
||||||
for (ty.field f in flds) {
|
for (ty.field f in flds) {
|
||||||
auto elt_align = align_of(cx, f.ty);
|
auto elt_align = align_of(bcx, f.ty);
|
||||||
auto elt_size = size_of(cx, f.ty);
|
bcx = elt_align.bcx;
|
||||||
auto aligned_off = align_to(cx, off, elt_align);
|
auto elt_size = size_of(bcx, f.ty);
|
||||||
off = cx.build.Add(aligned_off, elt_size);
|
bcx = elt_size.bcx;
|
||||||
max_align = umax(cx, max_align, elt_align);
|
auto aligned_off = align_to(bcx, off, elt_align.val);
|
||||||
|
off = cx.build.Add(aligned_off, elt_size.val);
|
||||||
|
max_align = umax(bcx, max_align, elt_align.val);
|
||||||
}
|
}
|
||||||
off = align_to(cx, off, max_align);
|
off = align_to(bcx, off, max_align);
|
||||||
ret off;
|
ret res(bcx, off);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn dynamic_align_of(@block_ctxt cx, @ty.t t) -> ValueRef {
|
fn dynamic_align_of(@block_ctxt cx, @ty.t t) -> result {
|
||||||
alt (t.struct) {
|
alt (t.struct) {
|
||||||
case (ty.ty_param(?p)) {
|
case (ty.ty_param(?p)) {
|
||||||
auto aptr = field_of_tydesc(cx, t, abi.tydesc_field_align);
|
auto aptr = field_of_tydesc(cx, t, abi.tydesc_field_align);
|
||||||
ret cx.build.Load(aptr);
|
ret res(aptr.bcx, aptr.bcx.build.Load(aptr.val));
|
||||||
}
|
}
|
||||||
case (ty.ty_tup(?elts)) {
|
case (ty.ty_tup(?elts)) {
|
||||||
auto a = C_int(1);
|
auto a = C_int(1);
|
||||||
|
auto bcx = cx;
|
||||||
for (@ty.t e in elts) {
|
for (@ty.t e in elts) {
|
||||||
a = umax(cx, a, align_of(cx, e));
|
auto align = align_of(bcx, e);
|
||||||
|
bcx = align.bcx;
|
||||||
|
a = umax(bcx, a, align.val);
|
||||||
}
|
}
|
||||||
ret a;
|
ret res(bcx, a);
|
||||||
}
|
}
|
||||||
case (ty.ty_rec(?flds)) {
|
case (ty.ty_rec(?flds)) {
|
||||||
auto a = C_int(1);
|
auto a = C_int(1);
|
||||||
|
auto bcx = cx;
|
||||||
for (ty.field f in flds) {
|
for (ty.field f in flds) {
|
||||||
a = umax(cx, a, align_of(cx, f.ty));
|
auto align = align_of(bcx, f.ty);
|
||||||
|
bcx = align.bcx;
|
||||||
|
a = umax(bcx, a, align.val);
|
||||||
}
|
}
|
||||||
ret a;
|
ret res(bcx, a);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -774,7 +787,7 @@ fn dynamic_align_of(@block_ctxt cx, @ty.t t) -> ValueRef {
|
|||||||
// align_of, above.
|
// align_of, above.
|
||||||
|
|
||||||
fn GEP_tup_like(@block_ctxt cx, @ty.t t,
|
fn GEP_tup_like(@block_ctxt cx, @ty.t t,
|
||||||
ValueRef base, vec[int] ixs) -> ValueRef {
|
ValueRef base, vec[int] ixs) -> result {
|
||||||
|
|
||||||
check (ty.type_is_tup_like(t));
|
check (ty.type_is_tup_like(t));
|
||||||
|
|
||||||
@ -785,7 +798,7 @@ fn GEP_tup_like(@block_ctxt cx, @ty.t t,
|
|||||||
for (int i in ixs) {
|
for (int i in ixs) {
|
||||||
v += C_int(i);
|
v += C_int(i);
|
||||||
}
|
}
|
||||||
ret cx.build.GEP(base, v);
|
ret res(cx, cx.build.GEP(base, v));
|
||||||
}
|
}
|
||||||
|
|
||||||
// It is a dynamic-containing type that, if we convert directly to an LLVM
|
// It is a dynamic-containing type that, if we convert directly to an LLVM
|
||||||
@ -856,14 +869,16 @@ fn GEP_tup_like(@block_ctxt cx, @ty.t t,
|
|||||||
|
|
||||||
auto s = split_type(t, ixs, 0u);
|
auto s = split_type(t, ixs, 0u);
|
||||||
auto prefix_ty = ty.plain_ty(ty.ty_tup(s.prefix));
|
auto prefix_ty = ty.plain_ty(ty.ty_tup(s.prefix));
|
||||||
auto sz = size_of(cx, prefix_ty);
|
auto bcx = cx;
|
||||||
auto raw = cx.build.PointerCast(base, T_ptr(T_i8()));
|
auto sz = size_of(bcx, prefix_ty);
|
||||||
auto bumped = cx.build.GEP(raw, vec(sz));
|
bcx = sz.bcx;
|
||||||
|
auto raw = bcx.build.PointerCast(base, T_ptr(T_i8()));
|
||||||
|
auto bumped = bcx.build.GEP(raw, vec(sz.val));
|
||||||
alt (s.target.struct) {
|
alt (s.target.struct) {
|
||||||
case (ty.ty_param(_)) { ret bumped; }
|
case (ty.ty_param(_)) { ret res(bcx, bumped); }
|
||||||
case (_) {
|
case (_) {
|
||||||
auto ty = T_ptr(type_of(cx.fcx.ccx, s.target));
|
auto ty = T_ptr(type_of(bcx.fcx.ccx, s.target));
|
||||||
ret cx.build.PointerCast(bumped, ty);
|
ret res(bcx, bcx.build.PointerCast(bumped, ty));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -893,9 +908,10 @@ fn trans_malloc(@block_ctxt cx, @ty.t t) -> result {
|
|||||||
// Given a type and a field index into its corresponding type descriptor,
|
// Given a type and a field index into its corresponding type descriptor,
|
||||||
// returns an LLVM ValueRef of that field from the tydesc, generating the
|
// returns an LLVM ValueRef of that field from the tydesc, generating the
|
||||||
// tydesc if necessary.
|
// tydesc if necessary.
|
||||||
fn field_of_tydesc(@block_ctxt cx, @ty.t t, int field) -> ValueRef {
|
fn field_of_tydesc(@block_ctxt cx, @ty.t t, int field) -> result {
|
||||||
auto tydesc = get_tydesc(cx, t);
|
auto tydesc = get_tydesc(cx, t);
|
||||||
ret cx.build.GEP(tydesc, vec(C_int(0), C_int(field)));
|
ret res(tydesc.bcx,
|
||||||
|
tydesc.bcx.build.GEP(tydesc.val, vec(C_int(0), C_int(field))));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Given a type containing ty params, build a vector containing a ValueRef for
|
// Given a type containing ty params, build a vector containing a ValueRef for
|
||||||
@ -940,10 +956,12 @@ fn linearize_ty_params(@block_ctxt cx, @ty.t t)
|
|||||||
ret tup(x.defs, x.vals);
|
ret tup(x.defs, x.vals);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_tydesc(&@block_ctxt cx, @ty.t t) -> ValueRef {
|
fn get_tydesc(&@block_ctxt cx, @ty.t t) -> result {
|
||||||
// Is the supplied type a type param? If so, return the passed-in tydesc.
|
// Is the supplied type a type param? If so, return the passed-in tydesc.
|
||||||
alt (ty.type_param(t)) {
|
alt (ty.type_param(t)) {
|
||||||
case (some[ast.def_id](?id)) { ret cx.fcx.lltydescs.get(id); }
|
case (some[ast.def_id](?id)) {
|
||||||
|
ret res(cx, cx.fcx.lltydescs.get(id));
|
||||||
|
}
|
||||||
case (none[ast.def_id]) { /* fall through */ }
|
case (none[ast.def_id]) { /* fall through */ }
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -953,13 +971,36 @@ fn get_tydesc(&@block_ctxt cx, @ty.t t) -> ValueRef {
|
|||||||
if (ty.count_ty_params(t) > 0u) {
|
if (ty.count_ty_params(t) > 0u) {
|
||||||
auto tys = linearize_ty_params(cx, t);
|
auto tys = linearize_ty_params(cx, t);
|
||||||
|
|
||||||
|
check (n_params == _vec.len[ast.def_id](tys._0));
|
||||||
|
check (n_params == _vec.len[ValueRef](tys._1));
|
||||||
|
|
||||||
if (!cx.fcx.ccx.tydescs.contains_key(t)) {
|
if (!cx.fcx.ccx.tydescs.contains_key(t)) {
|
||||||
make_tydesc(cx.fcx.ccx, t, tys._0);
|
make_tydesc(cx.fcx.ccx, t, tys._0);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto root = cx.fcx.ccx.tydescs.get(t);
|
auto root = cx.fcx.ccx.tydescs.get(t);
|
||||||
|
|
||||||
cx.fcx.ccx.sess.unimpl("derived type descriptors");
|
auto tydescs = cx.build.Alloca(T_array(T_ptr(T_tydesc()), n_params));
|
||||||
|
auto i = 0;
|
||||||
|
for (ValueRef td in tys._1) {
|
||||||
|
auto tdp = cx.build.GEP(tydescs, vec(C_int(0), C_int(i)));
|
||||||
|
cx.build.Store(td, tdp);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto bcx = cx;
|
||||||
|
auto sz = size_of(bcx, t);
|
||||||
|
bcx = sz.bcx;
|
||||||
|
auto align = align_of(bcx, t);
|
||||||
|
bcx = align.bcx;
|
||||||
|
|
||||||
|
auto v = trans_upcall(bcx, "upcall_get_type_desc",
|
||||||
|
vec(p2i(bcx.fcx.ccx.crate_ptr),
|
||||||
|
sz.val,
|
||||||
|
align.val,
|
||||||
|
C_int(n_params as int),
|
||||||
|
bcx.build.PtrToInt(tydescs, T_int())));
|
||||||
|
|
||||||
|
ret res(v.bcx, v.bcx.build.IntToPtr(v.val, T_ptr(T_tydesc())));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Otherwise, generate a tydesc if necessary, and return it.
|
// Otherwise, generate a tydesc if necessary, and return it.
|
||||||
@ -967,7 +1008,7 @@ fn get_tydesc(&@block_ctxt cx, @ty.t t) -> ValueRef {
|
|||||||
let vec[ast.def_id] defs = vec();
|
let vec[ast.def_id] defs = vec();
|
||||||
make_tydesc(cx.fcx.ccx, t, defs);
|
make_tydesc(cx.fcx.ccx, t, defs);
|
||||||
}
|
}
|
||||||
ret cx.fcx.ccx.tydescs.get(t);
|
ret res(cx, cx.fcx.ccx.tydescs.get(t));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn make_tydesc(@crate_ctxt cx, @ty.t t, vec[ast.def_id] typaram_defs) {
|
fn make_tydesc(@crate_ctxt cx, @ty.t t, vec[ast.def_id] typaram_defs) {
|
||||||
@ -1437,20 +1478,20 @@ fn iter_sequence(@block_ctxt cx,
|
|||||||
C_int(abi.vec_elt_fill)));
|
C_int(abi.vec_elt_fill)));
|
||||||
|
|
||||||
auto llunit_ty = type_of(cx.fcx.ccx, elt_ty);
|
auto llunit_ty = type_of(cx.fcx.ccx, elt_ty);
|
||||||
auto unit_sz = size_of(cx, elt_ty);
|
auto bcx = cx;
|
||||||
|
auto unit_sz = size_of(bcx, elt_ty);
|
||||||
|
bcx = unit_sz.bcx;
|
||||||
|
|
||||||
auto len = cx.build.Load(lenptr);
|
auto len = bcx.build.Load(lenptr);
|
||||||
if (trailing_null) {
|
if (trailing_null) {
|
||||||
len = cx.build.Sub(len, unit_sz);
|
len = bcx.build.Sub(len, unit_sz.val);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto r = res(cx, C_nil());
|
|
||||||
|
|
||||||
auto cond_cx = new_scope_block_ctxt(cx, "sequence-iter cond");
|
auto cond_cx = new_scope_block_ctxt(cx, "sequence-iter cond");
|
||||||
auto body_cx = new_scope_block_ctxt(cx, "sequence-iter body");
|
auto body_cx = new_scope_block_ctxt(cx, "sequence-iter body");
|
||||||
auto next_cx = new_sub_block_ctxt(cx, "next");
|
auto next_cx = new_sub_block_ctxt(cx, "next");
|
||||||
|
|
||||||
cx.build.Br(cond_cx.llbb);
|
bcx.build.Br(cond_cx.llbb);
|
||||||
|
|
||||||
auto ix = cond_cx.build.Phi(T_int(), vec(C_int(0)), vec(cx.llbb));
|
auto ix = cond_cx.build.Phi(T_int(), vec(C_int(0)), vec(cx.llbb));
|
||||||
auto scaled_ix = cond_cx.build.Phi(T_int(),
|
auto scaled_ix = cond_cx.build.Phi(T_int(),
|
||||||
@ -1465,7 +1506,7 @@ fn iter_sequence(@block_ctxt cx,
|
|||||||
load_scalar_or_boxed(body_cx, elt, elt_ty),
|
load_scalar_or_boxed(body_cx, elt, elt_ty),
|
||||||
elt_ty);
|
elt_ty);
|
||||||
auto next_ix = body_res.bcx.build.Add(ix, C_int(1));
|
auto next_ix = body_res.bcx.build.Add(ix, C_int(1));
|
||||||
auto next_scaled_ix = body_res.bcx.build.Add(scaled_ix, unit_sz);
|
auto next_scaled_ix = body_res.bcx.build.Add(scaled_ix, unit_sz.val);
|
||||||
|
|
||||||
cond_cx.build.AddIncomingToPhi(ix, vec(next_ix),
|
cond_cx.build.AddIncomingToPhi(ix, vec(next_ix),
|
||||||
vec(body_res.bcx.llbb));
|
vec(body_res.bcx.llbb));
|
||||||
@ -1504,7 +1545,8 @@ fn call_tydesc_glue_full(@block_ctxt cx, ValueRef v,
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn call_tydesc_glue(@block_ctxt cx, ValueRef v, @ty.t t, int field) {
|
fn call_tydesc_glue(@block_ctxt cx, ValueRef v, @ty.t t, int field) {
|
||||||
call_tydesc_glue_full(cx, v, get_tydesc(cx, t), field);
|
auto td = get_tydesc(cx, t);
|
||||||
|
call_tydesc_glue_full(td.bcx, v, td.val, field);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn incr_all_refcnts(@block_ctxt cx,
|
fn incr_all_refcnts(@block_ctxt cx,
|
||||||
@ -1565,8 +1607,8 @@ fn memcpy_ty(@block_ctxt cx,
|
|||||||
@ty.t t) -> result {
|
@ty.t t) -> result {
|
||||||
if (ty.type_has_dynamic_size(t)) {
|
if (ty.type_has_dynamic_size(t)) {
|
||||||
auto llszptr = field_of_tydesc(cx, t, abi.tydesc_field_size);
|
auto llszptr = field_of_tydesc(cx, t, abi.tydesc_field_size);
|
||||||
auto llsz = cx.build.Load(llszptr);
|
auto llsz = llszptr.bcx.build.Load(llszptr.val);
|
||||||
ret call_memcpy(cx, dst, src, llsz);
|
ret call_memcpy(llszptr.bcx, dst, src, llsz);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
ret res(cx, cx.build.Store(cx.build.Load(src), dst));
|
ret res(cx, cx.build.Store(cx.build.Load(src), dst));
|
||||||
@ -2182,14 +2224,17 @@ fn trans_path(@block_ctxt cx, &ast.path p, &option.t[ast.def] dopt,
|
|||||||
auto tys = ty.resolve_ty_params(fn_item, monoty);
|
auto tys = ty.resolve_ty_params(fn_item, monoty);
|
||||||
|
|
||||||
if (_vec.len[@ty.t](tys) != 0u) {
|
if (_vec.len[@ty.t](tys) != 0u) {
|
||||||
|
auto bcx = cx;
|
||||||
let vec[ValueRef] tydescs = vec();
|
let vec[ValueRef] tydescs = vec();
|
||||||
for (@ty.t t in tys) {
|
for (@ty.t t in tys) {
|
||||||
append[ValueRef](tydescs,
|
auto td = get_tydesc(bcx, t);
|
||||||
get_tydesc(cx, t));
|
bcx = td.bcx;
|
||||||
|
append[ValueRef](tydescs, td.val);
|
||||||
}
|
}
|
||||||
auto gen = rec( item_type = ty.item_ty(fn_item)._1,
|
auto gen = rec( item_type = ty.item_ty(fn_item)._1,
|
||||||
tydescs = tydescs );
|
tydescs = tydescs );
|
||||||
lv = rec(generic = some[generic_info](gen)
|
lv = rec(res = res(bcx, lv.res.val),
|
||||||
|
generic = some[generic_info](gen)
|
||||||
with lv);
|
with lv);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2236,12 +2281,12 @@ fn trans_field(@block_ctxt cx, &ast.span sp, @ast.expr base,
|
|||||||
case (ty.ty_tup(?fields)) {
|
case (ty.ty_tup(?fields)) {
|
||||||
let uint ix = ty.field_num(cx.fcx.ccx.sess, sp, field);
|
let uint ix = ty.field_num(cx.fcx.ccx.sess, sp, field);
|
||||||
auto v = GEP_tup_like(r.bcx, t, r.val, vec(0, ix as int));
|
auto v = GEP_tup_like(r.bcx, t, r.val, vec(0, ix as int));
|
||||||
ret lval_mem(r.bcx, v);
|
ret lval_mem(v.bcx, v.val);
|
||||||
}
|
}
|
||||||
case (ty.ty_rec(?fields)) {
|
case (ty.ty_rec(?fields)) {
|
||||||
let uint ix = ty.field_idx(cx.fcx.ccx.sess, sp, field, fields);
|
let uint ix = ty.field_idx(cx.fcx.ccx.sess, sp, field, fields);
|
||||||
auto v = GEP_tup_like(r.bcx, t, r.val, vec(0, ix as int));
|
auto v = GEP_tup_like(r.bcx, t, r.val, vec(0, ix as int));
|
||||||
ret lval_mem(r.bcx, v);
|
ret lval_mem(v.bcx, v.val);
|
||||||
}
|
}
|
||||||
case (ty.ty_obj(?methods)) {
|
case (ty.ty_obj(?methods)) {
|
||||||
let uint ix = ty.method_idx(cx.fcx.ccx.sess, sp, field, methods);
|
let uint ix = ty.method_idx(cx.fcx.ccx.sess, sp, field, methods);
|
||||||
@ -2267,20 +2312,22 @@ fn trans_index(@block_ctxt cx, &ast.span sp, @ast.expr base,
|
|||||||
lv = autoderef(lv.bcx, lv.val, ty.expr_ty(base));
|
lv = autoderef(lv.bcx, lv.val, ty.expr_ty(base));
|
||||||
auto ix = trans_expr(lv.bcx, idx);
|
auto ix = trans_expr(lv.bcx, idx);
|
||||||
auto v = lv.val;
|
auto v = lv.val;
|
||||||
|
auto bcx = ix.bcx;
|
||||||
|
|
||||||
auto llunit_ty = node_type(cx.fcx.ccx, ann);
|
auto llunit_ty = node_type(cx.fcx.ccx, ann);
|
||||||
auto unit_sz = size_of(cx, node_ann_type(cx.fcx.ccx, ann));
|
auto unit_sz = size_of(bcx, node_ann_type(cx.fcx.ccx, ann));
|
||||||
auto scaled_ix = ix.bcx.build.Mul(ix.val, unit_sz);
|
bcx = unit_sz.bcx;
|
||||||
|
auto scaled_ix = bcx.build.Mul(ix.val, unit_sz.val);
|
||||||
|
|
||||||
auto lim = ix.bcx.build.GEP(v, vec(C_int(0), C_int(abi.vec_elt_fill)));
|
auto lim = bcx.build.GEP(v, vec(C_int(0), C_int(abi.vec_elt_fill)));
|
||||||
lim = ix.bcx.build.Load(lim);
|
lim = bcx.build.Load(lim);
|
||||||
|
|
||||||
auto bounds_check = ix.bcx.build.ICmp(lib.llvm.LLVMIntULT,
|
auto bounds_check = bcx.build.ICmp(lib.llvm.LLVMIntULT,
|
||||||
scaled_ix, lim);
|
scaled_ix, lim);
|
||||||
|
|
||||||
auto fail_cx = new_sub_block_ctxt(ix.bcx, "fail");
|
auto fail_cx = new_sub_block_ctxt(bcx, "fail");
|
||||||
auto next_cx = new_sub_block_ctxt(ix.bcx, "next");
|
auto next_cx = new_sub_block_ctxt(bcx, "next");
|
||||||
ix.bcx.build.CondBr(bounds_check, next_cx.llbb, fail_cx.llbb);
|
bcx.build.CondBr(bounds_check, next_cx.llbb, fail_cx.llbb);
|
||||||
|
|
||||||
// fail: bad bounds check.
|
// fail: bad bounds check.
|
||||||
auto fail_res = trans_fail(fail_cx, sp, "bounds check");
|
auto fail_res = trans_fail(fail_cx, sp, "bounds check");
|
||||||
@ -2590,7 +2637,8 @@ fn trans_bind(@block_ctxt cx, @ast.expr f,
|
|||||||
vec(C_int(0),
|
vec(C_int(0),
|
||||||
C_int(abi.closure_elt_tydesc)));
|
C_int(abi.closure_elt_tydesc)));
|
||||||
auto bindings_tydesc = get_tydesc(bcx, bindings_ty);
|
auto bindings_tydesc = get_tydesc(bcx, bindings_ty);
|
||||||
bcx.build.Store(bindings_tydesc, bound_tydesc);
|
bcx = bindings_tydesc.bcx;
|
||||||
|
bcx.build.Store(bindings_tydesc.val, bound_tydesc);
|
||||||
|
|
||||||
// Store thunk-target.
|
// Store thunk-target.
|
||||||
auto bound_target =
|
auto bound_target =
|
||||||
@ -2740,16 +2788,18 @@ fn trans_vec(@block_ctxt cx, vec[@ast.expr] args,
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto llunit_ty = type_of(cx.fcx.ccx, unit_ty);
|
auto llunit_ty = type_of(cx.fcx.ccx, unit_ty);
|
||||||
auto unit_sz = size_of(cx, unit_ty);
|
auto bcx = cx;
|
||||||
|
auto unit_sz = size_of(bcx, unit_ty);
|
||||||
|
bcx = unit_sz.bcx;
|
||||||
auto data_sz = llvm.LLVMConstMul(C_int(_vec.len[@ast.expr](args) as int),
|
auto data_sz = llvm.LLVMConstMul(C_int(_vec.len[@ast.expr](args) as int),
|
||||||
unit_sz);
|
unit_sz.val);
|
||||||
|
|
||||||
// FIXME: pass tydesc properly.
|
// FIXME: pass tydesc properly.
|
||||||
auto sub = trans_upcall(cx, "upcall_new_vec", vec(data_sz, C_int(0)));
|
auto sub = trans_upcall(bcx, "upcall_new_vec", vec(data_sz, C_int(0)));
|
||||||
|
|
||||||
auto llty = type_of(cx.fcx.ccx, t);
|
auto llty = type_of(bcx.fcx.ccx, t);
|
||||||
auto vec_val = sub.bcx.build.IntToPtr(sub.val, llty);
|
auto vec_val = sub.bcx.build.IntToPtr(sub.val, llty);
|
||||||
find_scope_cx(cx).cleanups += clean(bind drop_ty(_, vec_val, t));
|
find_scope_cx(bcx).cleanups += clean(bind drop_ty(_, vec_val, t));
|
||||||
|
|
||||||
auto body = sub.bcx.build.GEP(vec_val, vec(C_int(0),
|
auto body = sub.bcx.build.GEP(vec_val, vec(C_int(0),
|
||||||
C_int(abi.vec_elt_data)));
|
C_int(abi.vec_elt_data)));
|
||||||
@ -3044,8 +3094,8 @@ fn init_local(@block_ctxt cx, @ast.local local) -> result {
|
|||||||
}
|
}
|
||||||
case (_) {
|
case (_) {
|
||||||
if (middle.ty.type_has_dynamic_size(ty)) {
|
if (middle.ty.type_has_dynamic_size(ty)) {
|
||||||
auto llsz = size_of(cx, ty);
|
auto llsz = size_of(bcx, ty);
|
||||||
bcx = call_bzero(cx, llptr, llsz).bcx;
|
bcx = call_bzero(llsz.bcx, llptr, llsz.val).bcx;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
auto llty = type_of(bcx.fcx.ccx, ty);
|
auto llty = type_of(bcx.fcx.ccx, ty);
|
||||||
@ -3179,14 +3229,16 @@ iter block_locals(&ast.block b) -> @ast.local {
|
|||||||
fn alloc_local(@block_ctxt cx, @ast.local local) -> result {
|
fn alloc_local(@block_ctxt cx, @ast.local local) -> result {
|
||||||
auto t = node_ann_type(cx.fcx.ccx, local.ann);
|
auto t = node_ann_type(cx.fcx.ccx, local.ann);
|
||||||
auto val = C_int(0);
|
auto val = C_int(0);
|
||||||
|
auto bcx = cx;
|
||||||
if (ty.type_has_dynamic_size(t)) {
|
if (ty.type_has_dynamic_size(t)) {
|
||||||
auto n = size_of(cx, t);
|
auto n = size_of(bcx, t);
|
||||||
val = cx.build.ArrayAlloca(T_i8(), n);
|
bcx = n.bcx;
|
||||||
|
val = bcx.build.ArrayAlloca(T_i8(), n.val);
|
||||||
} else {
|
} else {
|
||||||
val = cx.build.Alloca(type_of(cx.fcx.ccx, t));
|
val = bcx.build.Alloca(type_of(cx.fcx.ccx, t));
|
||||||
}
|
}
|
||||||
cx.fcx.lllocals.insert(local.id, val);
|
bcx.fcx.lllocals.insert(local.id, val);
|
||||||
ret res(cx, val);
|
ret res(bcx, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn trans_block(@block_ctxt cx, &ast.block b) -> result {
|
fn trans_block(@block_ctxt cx, &ast.block b) -> result {
|
||||||
@ -3526,43 +3578,45 @@ fn trans_obj(@crate_ctxt cx, &ast._obj ob, ast.def_id oid,
|
|||||||
|
|
||||||
// Malloc a box for the body.
|
// Malloc a box for the body.
|
||||||
auto r = trans_malloc_inner(bcx, llobj_body_ty);
|
auto r = trans_malloc_inner(bcx, llobj_body_ty);
|
||||||
|
bcx = r.bcx;
|
||||||
auto box = r.val;
|
auto box = r.val;
|
||||||
auto rc = r.bcx.build.GEP(box,
|
auto rc = bcx.build.GEP(box,
|
||||||
|
vec(C_int(0),
|
||||||
|
C_int(abi.box_rc_field_refcnt)));
|
||||||
|
auto body = bcx.build.GEP(box,
|
||||||
vec(C_int(0),
|
vec(C_int(0),
|
||||||
C_int(abi.box_rc_field_refcnt)));
|
C_int(abi.box_rc_field_body)));
|
||||||
auto body = r.bcx.build.GEP(box,
|
bcx.build.Store(C_int(1), rc);
|
||||||
vec(C_int(0),
|
|
||||||
C_int(abi.box_rc_field_body)));
|
|
||||||
r.bcx.build.Store(C_int(1), rc);
|
|
||||||
|
|
||||||
// Store body tydesc.
|
// Store body tydesc.
|
||||||
auto body_tydesc =
|
auto body_tydesc =
|
||||||
r.bcx.build.GEP(body,
|
bcx.build.GEP(body,
|
||||||
vec(C_int(0),
|
vec(C_int(0),
|
||||||
C_int(abi.obj_body_elt_tydesc)));
|
C_int(abi.obj_body_elt_tydesc)));
|
||||||
|
|
||||||
auto fields_tydesc = get_tydesc(r.bcx, fields_ty);
|
auto fields_tydesc = get_tydesc(r.bcx, fields_ty);
|
||||||
r.bcx.build.Store(fields_tydesc, body_tydesc);
|
bcx = fields_tydesc.bcx;
|
||||||
|
bcx.build.Store(fields_tydesc.val, body_tydesc);
|
||||||
|
|
||||||
// Copy args into body fields.
|
// Copy args into body fields.
|
||||||
auto body_fields =
|
auto body_fields =
|
||||||
r.bcx.build.GEP(body,
|
bcx.build.GEP(body,
|
||||||
vec(C_int(0),
|
vec(C_int(0),
|
||||||
C_int(abi.obj_body_elt_fields)));
|
C_int(abi.obj_body_elt_fields)));
|
||||||
|
|
||||||
let int i = 0;
|
let int i = 0;
|
||||||
for (ast.obj_field f in ob.fields) {
|
for (ast.obj_field f in ob.fields) {
|
||||||
auto arg = r.bcx.fcx.llargs.get(f.id);
|
auto arg = bcx.fcx.llargs.get(f.id);
|
||||||
arg = load_scalar_or_boxed(r.bcx, arg, arg_tys.(i).ty);
|
arg = load_scalar_or_boxed(bcx, arg, arg_tys.(i).ty);
|
||||||
auto field = r.bcx.build.GEP(body_fields,
|
auto field = bcx.build.GEP(body_fields,
|
||||||
vec(C_int(0),C_int(i)));
|
vec(C_int(0),C_int(i)));
|
||||||
r = copy_ty(r.bcx, INIT, field, arg, arg_tys.(i).ty);
|
bcx = copy_ty(bcx, INIT, field, arg, arg_tys.(i).ty).bcx;
|
||||||
i += 1;
|
i += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Store box ptr in outer pair.
|
// Store box ptr in outer pair.
|
||||||
auto p = r.bcx.build.PointerCast(box, llbox_ty);
|
auto p = bcx.build.PointerCast(box, llbox_ty);
|
||||||
r.bcx.build.Store(p, pair_box);
|
bcx.build.Store(p, pair_box);
|
||||||
}
|
}
|
||||||
bcx.build.Ret(bcx.build.Load(pair));
|
bcx.build.Ret(bcx.build.Load(pair));
|
||||||
}
|
}
|
||||||
@ -3983,13 +4037,9 @@ fn create_typedefs(@crate_ctxt cx) {
|
|||||||
llvm.LLVMAddTypeName(cx.llmod, _str.buf("rust_tydesc"), T_tydesc());
|
llvm.LLVMAddTypeName(cx.llmod, _str.buf("rust_tydesc"), T_tydesc());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn crate_constant(@crate_ctxt cx) -> ValueRef {
|
fn create_crate_constant(@crate_ctxt cx) {
|
||||||
|
|
||||||
let ValueRef crate_ptr =
|
let ValueRef crate_addr = p2i(cx.crate_ptr);
|
||||||
llvm.LLVMAddGlobal(cx.llmod, T_crate(),
|
|
||||||
_str.buf("rust_crate"));
|
|
||||||
|
|
||||||
let ValueRef crate_addr = p2i(crate_ptr);
|
|
||||||
|
|
||||||
let ValueRef activate_glue_off =
|
let ValueRef activate_glue_off =
|
||||||
llvm.LLVMConstSub(p2i(cx.glues.activate_glue), crate_addr);
|
llvm.LLVMConstSub(p2i(cx.glues.activate_glue), crate_addr);
|
||||||
@ -4002,7 +4052,7 @@ fn crate_constant(@crate_ctxt cx) -> ValueRef {
|
|||||||
|
|
||||||
let ValueRef crate_val =
|
let ValueRef crate_val =
|
||||||
C_struct(vec(C_null(T_int()), // ptrdiff_t image_base_off
|
C_struct(vec(C_null(T_int()), // ptrdiff_t image_base_off
|
||||||
p2i(crate_ptr), // uintptr_t self_addr
|
p2i(cx.crate_ptr), // uintptr_t self_addr
|
||||||
C_null(T_int()), // ptrdiff_t debug_abbrev_off
|
C_null(T_int()), // ptrdiff_t debug_abbrev_off
|
||||||
C_null(T_int()), // size_t debug_abbrev_sz
|
C_null(T_int()), // size_t debug_abbrev_sz
|
||||||
C_null(T_int()), // ptrdiff_t debug_info_off
|
C_null(T_int()), // ptrdiff_t debug_info_off
|
||||||
@ -4017,8 +4067,7 @@ fn crate_constant(@crate_ctxt cx) -> ValueRef {
|
|||||||
C_null(T_int()) // int n_libs
|
C_null(T_int()) // int n_libs
|
||||||
));
|
));
|
||||||
|
|
||||||
llvm.LLVMSetInitializer(crate_ptr, crate_val);
|
llvm.LLVMSetInitializer(cx.crate_ptr, crate_val);
|
||||||
ret crate_ptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn trans_main_fn(@crate_ctxt cx, ValueRef llcrate) {
|
fn trans_main_fn(@crate_ctxt cx, ValueRef llcrate) {
|
||||||
@ -4207,6 +4256,8 @@ fn trans_crate(session.session sess, @ast.crate crate, str output,
|
|||||||
llvm.LLVMSetDataLayout(llmod, _str.buf(x86.get_data_layout()));
|
llvm.LLVMSetDataLayout(llmod, _str.buf(x86.get_data_layout()));
|
||||||
llvm.LLVMSetTarget(llmod, _str.buf(x86.get_target_triple()));
|
llvm.LLVMSetTarget(llmod, _str.buf(x86.get_target_triple()));
|
||||||
auto td = mk_target_data(x86.get_data_layout());
|
auto td = mk_target_data(x86.get_data_layout());
|
||||||
|
let ValueRef crate_ptr =
|
||||||
|
llvm.LLVMAddGlobal(llmod, T_crate(), _str.buf("rust_crate"));
|
||||||
|
|
||||||
llvm.LLVMSetModuleInlineAsm(llmod, _str.buf(x86.get_module_asm()));
|
llvm.LLVMSetModuleInlineAsm(llmod, _str.buf(x86.get_module_asm()));
|
||||||
|
|
||||||
@ -4221,6 +4272,7 @@ fn trans_crate(session.session sess, @ast.crate crate, str output,
|
|||||||
auto cx = @rec(sess = sess,
|
auto cx = @rec(sess = sess,
|
||||||
llmod = llmod,
|
llmod = llmod,
|
||||||
td = td,
|
td = td,
|
||||||
|
crate_ptr = crate_ptr,
|
||||||
upcalls = new_str_hash[ValueRef](),
|
upcalls = new_str_hash[ValueRef](),
|
||||||
intrinsics = intrinsics,
|
intrinsics = intrinsics,
|
||||||
item_names = new_str_hash[ValueRef](),
|
item_names = new_str_hash[ValueRef](),
|
||||||
@ -4245,8 +4297,9 @@ fn trans_crate(session.session sess, @ast.crate crate, str output,
|
|||||||
|
|
||||||
trans_mod(cx, crate.node.module);
|
trans_mod(cx, crate.node.module);
|
||||||
trans_exit_task_glue(cx);
|
trans_exit_task_glue(cx);
|
||||||
|
create_crate_constant(cx);
|
||||||
if (!shared) {
|
if (!shared) {
|
||||||
trans_main_fn(cx, crate_constant(cx));
|
trans_main_fn(cx, cx.crate_ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
check_module(llmod);
|
check_module(llmod);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user