提交 8640e67e 编写于 作者: T Tim Chevalier

Add a precondition to GEP_tup_like

上级 2b98eccf
...@@ -610,6 +610,8 @@ fn align_elements(cx: @block_ctxt, elts: [ty::t]) -> result { ...@@ -610,6 +610,8 @@ fn align_elements(cx: @block_ctxt, elts: [ty::t]) -> result {
} }
fn dynamic_align_of(cx: @block_ctxt, t: ty::t) -> result { fn dynamic_align_of(cx: @block_ctxt, t: ty::t) -> result {
// FIXME: Typestate constraint that shows this alt is
// exhaustive
alt ty::struct(bcx_tcx(cx), t) { alt ty::struct(bcx_tcx(cx), t) {
ty::ty_param(p, _) { ty::ty_param(p, _) {
let aptr = field_of_tydesc(cx, t, false, abi::tydesc_field_align); let aptr = field_of_tydesc(cx, t, false, abi::tydesc_field_align);
...@@ -668,9 +670,8 @@ fn bump_ptr(bcx: @block_ctxt, t: ty::t, base: ValueRef, sz: ValueRef) -> ...@@ -668,9 +670,8 @@ fn bump_ptr(bcx: @block_ctxt, t: ty::t, base: ValueRef, sz: ValueRef) ->
// ty::struct and knows what to do when it runs into a ty_param stuck in the // ty::struct and knows what to do when it runs into a ty_param stuck in the
// middle of the thing it's GEP'ing into. Much like size_of and align_of, // middle of the thing it's GEP'ing into. Much like size_of and align_of,
// above. // above.
fn GEP_tup_like(cx: @block_ctxt, t: ty::t, base: ValueRef, ixs: [int]) -> fn GEP_tup_like(cx: @block_ctxt, t: ty::t, base: ValueRef, ixs: [int])
result { : type_is_tup_like(cx, t) -> result {
assert (ty::type_is_tup_like(bcx_tcx(cx), t));
// It might be a static-known type. Handle this. // It might be a static-known type. Handle this.
if !ty::type_has_dynamic_size(bcx_tcx(cx), t) { if !ty::type_has_dynamic_size(bcx_tcx(cx), t) {
ret rslt(cx, GEPi(cx, base, ixs)); ret rslt(cx, GEPi(cx, base, ixs));
...@@ -785,6 +786,8 @@ fn GEP_tag(cx: @block_ctxt, llblobptr: ValueRef, tag_id: ast::def_id, ...@@ -785,6 +786,8 @@ fn GEP_tag(cx: @block_ctxt, llblobptr: ValueRef, tag_id: ast::def_id,
} else { llunionptr = llblobptr; } } else { llunionptr = llblobptr; }
// Do the GEP_tup_like(). // Do the GEP_tup_like().
// Silly check -- postcondition on mk_tup?
check type_is_tup_like(cx, tup_ty);
let rs = GEP_tup_like(cx, tup_ty, llunionptr, [0, ix as int]); let rs = GEP_tup_like(cx, tup_ty, llunionptr, [0, ix as int]);
// Cast the result to the appropriate type, if necessary. // Cast the result to the appropriate type, if necessary.
...@@ -1403,12 +1406,15 @@ fn trans_res_drop(cx: @block_ctxt, rs: ValueRef, did: ast::def_id, ...@@ -1403,12 +1406,15 @@ fn trans_res_drop(cx: @block_ctxt, rs: ValueRef, did: ast::def_id,
let drop_cx = new_sub_block_ctxt(cx, "drop res"); let drop_cx = new_sub_block_ctxt(cx, "drop res");
let next_cx = new_sub_block_ctxt(cx, "next"); let next_cx = new_sub_block_ctxt(cx, "next");
// Silly check
check type_is_tup_like(cx, tup_ty);
let drop_flag = GEP_tup_like(cx, tup_ty, rs, [0, 0]); let drop_flag = GEP_tup_like(cx, tup_ty, rs, [0, 0]);
cx = drop_flag.bcx; cx = drop_flag.bcx;
let null_test = IsNull(cx, Load(cx, drop_flag.val)); let null_test = IsNull(cx, Load(cx, drop_flag.val));
CondBr(cx, null_test, next_cx.llbb, drop_cx.llbb); CondBr(cx, null_test, next_cx.llbb, drop_cx.llbb);
cx = drop_cx; cx = drop_cx;
check type_is_tup_like(cx, tup_ty);
let val = GEP_tup_like(cx, tup_ty, rs, [0, 1]); let val = GEP_tup_like(cx, tup_ty, rs, [0, 1]);
cx = val.bcx; cx = val.bcx;
// Find and call the actual destructor. // Find and call the actual destructor.
...@@ -1641,10 +1647,15 @@ fn iter_variant(cx: @block_ctxt, a_tup: ValueRef, ...@@ -1641,10 +1647,15 @@ fn iter_variant(cx: @block_ctxt, a_tup: ValueRef,
ret cx; ret cx;
} }
/*
Typestate constraint that shows the unimpl case doesn't happen?
*/
alt ty::struct(bcx_tcx(cx), t) { alt ty::struct(bcx_tcx(cx), t) {
ty::ty_rec(fields) { ty::ty_rec(fields) {
let i: int = 0; let i: int = 0;
for fld: ty::field in fields { for fld: ty::field in fields {
// Silly check
check type_is_tup_like(cx, t);
let {bcx: bcx, val: llfld_a} = GEP_tup_like(cx, t, av, [0, i]); let {bcx: bcx, val: llfld_a} = GEP_tup_like(cx, t, av, [0, i]);
cx = f(bcx, llfld_a, fld.mt.ty); cx = f(bcx, llfld_a, fld.mt.ty);
i += 1; i += 1;
...@@ -1653,6 +1664,8 @@ fn iter_variant(cx: @block_ctxt, a_tup: ValueRef, ...@@ -1653,6 +1664,8 @@ fn iter_variant(cx: @block_ctxt, a_tup: ValueRef,
ty::ty_tup(args) { ty::ty_tup(args) {
let i = 0; let i = 0;
for arg in args { for arg in args {
// Silly check
check type_is_tup_like(cx, t);
let {bcx: bcx, val: llfld_a} = GEP_tup_like(cx, t, av, [0, i]); let {bcx: bcx, val: llfld_a} = GEP_tup_like(cx, t, av, [0, i]);
cx = f(bcx, llfld_a, arg); cx = f(bcx, llfld_a, arg);
i += 1; i += 1;
...@@ -1663,6 +1676,8 @@ fn iter_variant(cx: @block_ctxt, a_tup: ValueRef, ...@@ -1663,6 +1676,8 @@ fn iter_variant(cx: @block_ctxt, a_tup: ValueRef,
let inner1 = ty::substitute_type_params(tcx, tps, inner); let inner1 = ty::substitute_type_params(tcx, tps, inner);
let inner_t_s = ty::substitute_type_params(tcx, tps, inner); let inner_t_s = ty::substitute_type_params(tcx, tps, inner);
let tup_t = ty::mk_tup(tcx, [ty::mk_int(tcx), inner_t_s]); let tup_t = ty::mk_tup(tcx, [ty::mk_int(tcx), inner_t_s]);
// Silly check
check type_is_tup_like(cx, tup_t);
let {bcx: bcx, val: llfld_a} = GEP_tup_like(cx, tup_t, av, [0, 1]); let {bcx: bcx, val: llfld_a} = GEP_tup_like(cx, tup_t, av, [0, 1]);
ret f(bcx, llfld_a, inner1); ret f(bcx, llfld_a, inner1);
} }
...@@ -2543,11 +2558,15 @@ fn build_environment(bcx: @block_ctxt, lltydescs: [ValueRef], ...@@ -2543,11 +2558,15 @@ fn build_environment(bcx: @block_ctxt, lltydescs: [ValueRef],
// Copy expr values into boxed bindings. // Copy expr values into boxed bindings.
let i = 0u; let i = 0u;
// Silly check
check type_is_tup_like(bcx, closure_ty);
let bindings = let bindings =
GEP_tup_like(bcx, closure_ty, closure, GEP_tup_like(bcx, closure_ty, closure,
[0, abi::closure_elt_bindings]); [0, abi::closure_elt_bindings]);
bcx = bindings.bcx; bcx = bindings.bcx;
for lv: lval_result in bound_vals { for lv: lval_result in bound_vals {
// Also a silly check
check type_is_tup_like(bcx, bindings_ty);
let bound = let bound =
GEP_tup_like(bcx, bindings_ty, bindings.val, [0, i as int]); GEP_tup_like(bcx, bindings_ty, bindings.val, [0, i as int]);
bcx = bound.bcx; bcx = bound.bcx;
...@@ -2559,6 +2578,8 @@ fn build_environment(bcx: @block_ctxt, lltydescs: [ValueRef], ...@@ -2559,6 +2578,8 @@ fn build_environment(bcx: @block_ctxt, lltydescs: [ValueRef],
// If necessary, copy tydescs describing type parameters into the // If necessary, copy tydescs describing type parameters into the
// appropriate slot in the closure. // appropriate slot in the closure.
// Silly check as well
check type_is_tup_like(bcx, closure_ty);
let ty_params_slot = let ty_params_slot =
GEP_tup_like(bcx, closure_ty, closure, GEP_tup_like(bcx, closure_ty, closure,
[0, abi::closure_elt_ty_params]); [0, abi::closure_elt_ty_params]);
...@@ -2663,6 +2684,8 @@ fn load_environment(enclosing_cx: @block_ctxt, fcx: @fn_ctxt, envty: ty::t, ...@@ -2663,6 +2684,8 @@ fn load_environment(enclosing_cx: @block_ctxt, fcx: @fn_ctxt, envty: ty::t,
// If this is an aliasing closure/for-each body, we need to load // If this is an aliasing closure/for-each body, we need to load
// the iterbody. // the iterbody.
if !copying && !option::is_none(enclosing_cx.fcx.lliterbody) { if !copying && !option::is_none(enclosing_cx.fcx.lliterbody) {
// Silly check
check type_is_tup_like(bcx, ty);
let iterbodyptr = GEP_tup_like(bcx, ty, llclosure, path + [0]); let iterbodyptr = GEP_tup_like(bcx, ty, llclosure, path + [0]);
fcx.lliterbody = some(Load(bcx, iterbodyptr.val)); fcx.lliterbody = some(Load(bcx, iterbodyptr.val));
bcx = iterbodyptr.bcx; bcx = iterbodyptr.bcx;
...@@ -2671,6 +2694,8 @@ fn load_environment(enclosing_cx: @block_ctxt, fcx: @fn_ctxt, envty: ty::t, ...@@ -2671,6 +2694,8 @@ fn load_environment(enclosing_cx: @block_ctxt, fcx: @fn_ctxt, envty: ty::t,
// Load the actual upvars. // Load the actual upvars.
for upvar_def in *upvars { for upvar_def in *upvars {
// Silly check
check type_is_tup_like(bcx, ty);
let upvarptr = GEP_tup_like(bcx, ty, llclosure, path + [i as int]); let upvarptr = GEP_tup_like(bcx, ty, llclosure, path + [i as int]);
bcx = upvarptr.bcx; bcx = upvarptr.bcx;
let llupvarptr = upvarptr.val; let llupvarptr = upvarptr.val;
...@@ -2984,7 +3009,10 @@ fn trans_field_inner(cx: @block_ctxt, sp: span, v: ValueRef, t0: ty::t, ...@@ -2984,7 +3009,10 @@ fn trans_field_inner(cx: @block_ctxt, sp: span, v: ValueRef, t0: ty::t,
alt ty::struct(bcx_tcx(cx), t) { alt ty::struct(bcx_tcx(cx), t) {
ty::ty_rec(fields) { ty::ty_rec(fields) {
let ix: uint = ty::field_idx(bcx_ccx(cx).sess, sp, field, fields); let ix: uint = ty::field_idx(bcx_ccx(cx).sess, sp, field, fields);
let v = GEP_tup_like(r.bcx, t, r.val, [0, ix as int]); let r_bcx = r.bcx;
// Silly check
check type_is_tup_like(r_bcx, t);
let v = GEP_tup_like(r_bcx, t, r.val, [0, ix as int]);
ret lval_no_env(v.bcx, v.val, true); ret lval_no_env(v.bcx, v.val, true);
} }
ty::ty_obj(methods) { ty::ty_obj(methods) {
...@@ -3329,6 +3357,8 @@ fn trans_bind_thunk(cx: @local_ctxt, sp: span, incoming_fty: ty::t, ...@@ -3329,6 +3357,8 @@ fn trans_bind_thunk(cx: @local_ctxt, sp: span, incoming_fty: ty::t,
(fptr, C_null(T_opaque_closure_ptr(*bcx_ccx(bcx))), 0) (fptr, C_null(T_opaque_closure_ptr(*bcx_ccx(bcx))), 0)
} }
none. { none. {
// Silly check
check type_is_tup_like(bcx, closure_ty);
let {bcx: cx, val: pair} = let {bcx: cx, val: pair} =
GEP_tup_like(bcx, closure_ty, llclosure, GEP_tup_like(bcx, closure_ty, llclosure,
[0, abi::box_rc_field_body, [0, abi::box_rc_field_body,
...@@ -3368,6 +3398,8 @@ fn trans_bind_thunk(cx: @local_ctxt, sp: span, incoming_fty: ty::t, ...@@ -3368,6 +3398,8 @@ fn trans_bind_thunk(cx: @local_ctxt, sp: span, incoming_fty: ty::t,
// Copy in the type parameters. // Copy in the type parameters.
let i: uint = 0u; let i: uint = 0u;
while i < ty_param_count { while i < ty_param_count {
// Silly check
check type_is_tup_like(copy_args_bcx, closure_ty);
let lltyparam_ptr = let lltyparam_ptr =
GEP_tup_like(copy_args_bcx, closure_ty, llclosure, GEP_tup_like(copy_args_bcx, closure_ty, llclosure,
[0, abi::box_rc_field_body, [0, abi::box_rc_field_body,
...@@ -3391,6 +3423,8 @@ fn trans_bind_thunk(cx: @local_ctxt, sp: span, incoming_fty: ty::t, ...@@ -3391,6 +3423,8 @@ fn trans_bind_thunk(cx: @local_ctxt, sp: span, incoming_fty: ty::t,
// Arg provided at binding time; thunk copies it from // Arg provided at binding time; thunk copies it from
// closure. // closure.
some(e) { some(e) {
// Silly check
check type_is_tup_like(bcx, closure_ty);
let bound_arg = let bound_arg =
GEP_tup_like(bcx, closure_ty, llclosure, GEP_tup_like(bcx, closure_ty, llclosure,
[0, abi::box_rc_field_body, [0, abi::box_rc_field_body,
...@@ -3914,6 +3948,8 @@ fn trans_tup(cx: @block_ctxt, elts: [@ast::expr], id: ast::node_id) -> ...@@ -3914,6 +3948,8 @@ fn trans_tup(cx: @block_ctxt, elts: [@ast::expr], id: ast::node_id) ->
let e_ty = ty::expr_ty(cx.fcx.lcx.ccx.tcx, e); let e_ty = ty::expr_ty(cx.fcx.lcx.ccx.tcx, e);
let src = trans_lval(bcx, e); let src = trans_lval(bcx, e);
bcx = src.bcx; bcx = src.bcx;
// FIXME: constraint on argument?
check type_is_tup_like(bcx, t);
let dst_res = GEP_tup_like(bcx, t, tup_val, [0, i]); let dst_res = GEP_tup_like(bcx, t, tup_val, [0, i]);
bcx = move_val_if_temp(dst_res.bcx, INIT, dst_res.val, src, e_ty); bcx = move_val_if_temp(dst_res.bcx, INIT, dst_res.val, src, e_ty);
i += 1; i += 1;
...@@ -3943,6 +3979,8 @@ fn trans_rec(cx: @block_ctxt, fields: [ast::field], ...@@ -3943,6 +3979,8 @@ fn trans_rec(cx: @block_ctxt, fields: [ast::field],
alt ty::struct(bcx_tcx(cx), t) { ty::ty_rec(flds) { ty_fields = flds; } } alt ty::struct(bcx_tcx(cx), t) { ty::ty_rec(flds) { ty_fields = flds; } }
for tf: ty::field in ty_fields { for tf: ty::field in ty_fields {
let e_ty = tf.mt.ty; let e_ty = tf.mt.ty;
// FIXME: constraint on argument?
check type_is_tup_like(bcx, t);
let dst_res = GEP_tup_like(bcx, t, rec_val, [0, i]); let dst_res = GEP_tup_like(bcx, t, rec_val, [0, i]);
bcx = dst_res.bcx; bcx = dst_res.bcx;
let expr_provided = false; let expr_provided = false;
...@@ -3956,6 +3994,8 @@ fn trans_rec(cx: @block_ctxt, fields: [ast::field], ...@@ -3956,6 +3994,8 @@ fn trans_rec(cx: @block_ctxt, fields: [ast::field],
} }
} }
if !expr_provided { if !expr_provided {
// FIXME: constraint on argument?
check type_is_tup_like(bcx, t);
let src_res = GEP_tup_like(bcx, t, base_val, [0, i]); let src_res = GEP_tup_like(bcx, t, base_val, [0, i]);
src_res = src_res =
rslt(src_res.bcx, load_if_immediate(bcx, src_res.val, e_ty)); rslt(src_res.bcx, load_if_immediate(bcx, src_res.val, e_ty));
...@@ -5100,6 +5140,8 @@ fn populate_fn_ctxt_from_llself(fcx: @fn_ctxt, llself: val_self_pair) { ...@@ -5100,6 +5140,8 @@ fn populate_fn_ctxt_from_llself(fcx: @fn_ctxt, llself: val_self_pair) {
} }
i = 0; i = 0;
for f: ast::obj_field in fcx.lcx.obj_fields { for f: ast::obj_field in fcx.lcx.obj_fields {
// FIXME: silly check
check type_is_tup_like(bcx, fields_tup_ty);
let rslt = GEP_tup_like(bcx, fields_tup_ty, obj_fields, [0, i]); let rslt = GEP_tup_like(bcx, fields_tup_ty, obj_fields, [0, i]);
bcx = llstaticallocas_block_ctxt(fcx); bcx = llstaticallocas_block_ctxt(fcx);
let llfield = rslt.val; let llfield = rslt.val;
...@@ -5248,9 +5290,12 @@ fn trans_res_ctor(cx: @local_ctxt, sp: span, dtor: ast::_fn, ...@@ -5248,9 +5290,12 @@ fn trans_res_ctor(cx: @local_ctxt, sp: span, dtor: ast::_fn,
llretptr = BitCast(bcx, llretptr, llret_t); llretptr = BitCast(bcx, llretptr, llret_t);
} }
// FIXME: silly checks
check type_is_tup_like(bcx, tup_t);
let dst = GEP_tup_like(bcx, tup_t, llretptr, [0, 1]); let dst = GEP_tup_like(bcx, tup_t, llretptr, [0, 1]);
bcx = dst.bcx; bcx = dst.bcx;
bcx = copy_val(bcx, INIT, dst.val, arg, arg_t); bcx = copy_val(bcx, INIT, dst.val, arg, arg_t);
check type_is_tup_like(bcx, tup_t);
let flag = GEP_tup_like(bcx, tup_t, llretptr, [0, 0]); let flag = GEP_tup_like(bcx, tup_t, llretptr, [0, 0]);
bcx = flag.bcx; bcx = flag.bcx;
Store(bcx, C_int(1), flag.val); Store(bcx, C_int(1), flag.val);
......
...@@ -342,6 +342,8 @@ fn compile_submatch(bcx: @block_ctxt, m: match, vals: [ValueRef], f: mk_fail, ...@@ -342,6 +342,8 @@ fn compile_submatch(bcx: @block_ctxt, m: match, vals: [ValueRef], f: mk_fail,
for field_name: ast::ident in rec_fields { for field_name: ast::ident in rec_fields {
let ix: uint = let ix: uint =
ty::field_idx(ccx.sess, dummy_sp(), field_name, fields); ty::field_idx(ccx.sess, dummy_sp(), field_name, fields);
// not sure how to get rid of this check
check type_is_tup_like(bcx, rec_ty);
let r = trans::GEP_tup_like(bcx, rec_ty, val, [0, ix as int]); let r = trans::GEP_tup_like(bcx, rec_ty, val, [0, ix as int]);
rec_vals += [r.val]; rec_vals += [r.val];
bcx = r.bcx; bcx = r.bcx;
...@@ -359,6 +361,8 @@ fn compile_submatch(bcx: @block_ctxt, m: match, vals: [ValueRef], f: mk_fail, ...@@ -359,6 +361,8 @@ fn compile_submatch(bcx: @block_ctxt, m: match, vals: [ValueRef], f: mk_fail,
}; };
let tup_vals = [], i = 0u; let tup_vals = [], i = 0u;
while i < n_tup_elts { while i < n_tup_elts {
// how to get rid of this check?
check type_is_tup_like(bcx, tup_ty);
let r = trans::GEP_tup_like(bcx, tup_ty, val, [0, i as int]); let r = trans::GEP_tup_like(bcx, tup_ty, val, [0, i as int]);
tup_vals += [r.val]; tup_vals += [r.val];
bcx = r.bcx; bcx = r.bcx;
...@@ -603,6 +607,8 @@ fn bind_irrefutable_pat(bcx: @block_ctxt, pat: @ast::pat, val: ValueRef, ...@@ -603,6 +607,8 @@ fn bind_irrefutable_pat(bcx: @block_ctxt, pat: @ast::pat, val: ValueRef,
for f: ast::field_pat in fields { for f: ast::field_pat in fields {
let ix: uint = let ix: uint =
ty::field_idx(ccx.sess, pat.span, f.ident, rec_fields); ty::field_idx(ccx.sess, pat.span, f.ident, rec_fields);
// how to get rid of this check?
check type_is_tup_like(bcx, rec_ty);
let r = trans::GEP_tup_like(bcx, rec_ty, val, [0, ix as int]); let r = trans::GEP_tup_like(bcx, rec_ty, val, [0, ix as int]);
bcx = bind_irrefutable_pat(r.bcx, f.pat, r.val, table, make_copy); bcx = bind_irrefutable_pat(r.bcx, f.pat, r.val, table, make_copy);
} }
...@@ -611,6 +617,8 @@ fn bind_irrefutable_pat(bcx: @block_ctxt, pat: @ast::pat, val: ValueRef, ...@@ -611,6 +617,8 @@ fn bind_irrefutable_pat(bcx: @block_ctxt, pat: @ast::pat, val: ValueRef,
let tup_ty = ty::node_id_to_monotype(ccx.tcx, pat.id); let tup_ty = ty::node_id_to_monotype(ccx.tcx, pat.id);
let i = 0u; let i = 0u;
for elem in elems { for elem in elems {
// how to get rid of this check?
check type_is_tup_like(bcx, tup_ty);
let r = trans::GEP_tup_like(bcx, tup_ty, val, [0, i as int]); let r = trans::GEP_tup_like(bcx, tup_ty, val, [0, i as int]);
bcx = bind_irrefutable_pat(r.bcx, elem, r.val, table, make_copy); bcx = bind_irrefutable_pat(r.bcx, elem, r.val, table, make_copy);
i += 1u; i += 1u;
......
...@@ -121,11 +121,14 @@ fn trans_obj(cx: @local_ctxt, sp: span, ob: ast::_obj, ctor_id: ast::node_id, ...@@ -121,11 +121,14 @@ fn trans_obj(cx: @local_ctxt, sp: span, ob: ast::_obj, ctor_id: ast::node_id,
// the types of the object's fields, so that the fields can be freed // the types of the object's fields, so that the fields can be freed
// later. // later.
// postcondition on create_object_body_type?
check type_is_tup_like(bcx, body_ty);
let body_tydesc = let body_tydesc =
GEP_tup_like(bcx, body_ty, body, [0, abi::obj_body_elt_tydesc]); GEP_tup_like(bcx, body_ty, body, [0, abi::obj_body_elt_tydesc]);
bcx = body_tydesc.bcx; bcx = body_tydesc.bcx;
let ti = none; let ti = none;
check type_is_tup_like(bcx, body_ty);
let r = let r =
GEP_tup_like(bcx, body_ty, body, [0, abi::obj_body_elt_typarams]); GEP_tup_like(bcx, body_ty, body, [0, abi::obj_body_elt_typarams]);
bcx = r.bcx; bcx = r.bcx;
...@@ -151,6 +154,8 @@ fn trans_obj(cx: @local_ctxt, sp: span, ob: ast::_obj, ctor_id: ast::node_id, ...@@ -151,6 +154,8 @@ fn trans_obj(cx: @local_ctxt, sp: span, ob: ast::_obj, ctor_id: ast::node_id,
let i: int = 0; let i: int = 0;
for tp: ast::ty_param in ty_params { for tp: ast::ty_param in ty_params {
let typaram = bcx.fcx.lltydescs[i]; let typaram = bcx.fcx.lltydescs[i];
// Silly check
check type_is_tup_like(bcx, typarams_ty);
let capture = let capture =
GEP_tup_like(bcx, typarams_ty, body_typarams, [0, i]); GEP_tup_like(bcx, typarams_ty, body_typarams, [0, i]);
bcx = capture.bcx; bcx = capture.bcx;
...@@ -159,6 +164,8 @@ fn trans_obj(cx: @local_ctxt, sp: span, ob: ast::_obj, ctor_id: ast::node_id, ...@@ -159,6 +164,8 @@ fn trans_obj(cx: @local_ctxt, sp: span, ob: ast::_obj, ctor_id: ast::node_id,
} }
// Copy args into body fields. // Copy args into body fields.
// how to get rid of this check?
check type_is_tup_like(bcx, body_ty);
let body_fields = let body_fields =
GEP_tup_like(bcx, body_ty, body, [0, abi::obj_body_elt_fields]); GEP_tup_like(bcx, body_ty, body, [0, abi::obj_body_elt_fields]);
bcx = body_fields.bcx; bcx = body_fields.bcx;
...@@ -169,6 +176,8 @@ fn trans_obj(cx: @local_ctxt, sp: span, ob: ast::_obj, ctor_id: ast::node_id, ...@@ -169,6 +176,8 @@ fn trans_obj(cx: @local_ctxt, sp: span, ob: ast::_obj, ctor_id: ast::node_id,
let arg = load_if_immediate(bcx, arg1, arg_tys[i].ty); let arg = load_if_immediate(bcx, arg1, arg_tys[i].ty);
// TODO: can we just get fields_ty out of body_ty instead? // TODO: can we just get fields_ty out of body_ty instead?
let fields_ty: ty::t = ty::mk_tup(ccx.tcx, obj_fields); let fields_ty: ty::t = ty::mk_tup(ccx.tcx, obj_fields);
// Silly check
check type_is_tup_like(bcx, fields_ty);
let field = let field =
GEP_tup_like(bcx, fields_ty, body_fields.val, [0, i]); GEP_tup_like(bcx, fields_ty, body_fields.val, [0, i]);
bcx = field.bcx; bcx = field.bcx;
...@@ -314,6 +323,8 @@ fn trans_anon_obj(bcx: @block_ctxt, sp: span, anon_obj: ast::anon_obj, ...@@ -314,6 +323,8 @@ fn trans_anon_obj(bcx: @block_ctxt, sp: span, anon_obj: ast::anon_obj,
// the user of the object. So the tydesc is needed to keep track of // the user of the object. So the tydesc is needed to keep track of
// the types of the object's fields, so that the fields can be freed // the types of the object's fields, so that the fields can be freed
// later. // later.
// postcondition on create_object_body_type?
check type_is_tup_like(bcx, body_ty);
let body_tydesc = let body_tydesc =
GEP_tup_like(bcx, body_ty, body, [0, abi::obj_body_elt_tydesc]); GEP_tup_like(bcx, body_ty, body, [0, abi::obj_body_elt_tydesc]);
bcx = body_tydesc.bcx; bcx = body_tydesc.bcx;
...@@ -328,6 +339,7 @@ fn trans_anon_obj(bcx: @block_ctxt, sp: span, anon_obj: ast::anon_obj, ...@@ -328,6 +339,7 @@ fn trans_anon_obj(bcx: @block_ctxt, sp: span, anon_obj: ast::anon_obj,
// body. (This is something like saving the lexical environment of a // body. (This is something like saving the lexical environment of a
// function in its closure: the fields were passed to the object // function in its closure: the fields were passed to the object
// constructor and are now available to the object's methods. // constructor and are now available to the object's methods.
check type_is_tup_like(bcx, body_ty);
let body_fields = let body_fields =
GEP_tup_like(bcx, body_ty, body, [0, abi::obj_body_elt_fields]); GEP_tup_like(bcx, body_ty, body, [0, abi::obj_body_elt_fields]);
bcx = body_fields.bcx; bcx = body_fields.bcx;
...@@ -338,6 +350,8 @@ fn trans_anon_obj(bcx: @block_ctxt, sp: span, anon_obj: ast::anon_obj, ...@@ -338,6 +350,8 @@ fn trans_anon_obj(bcx: @block_ctxt, sp: span, anon_obj: ast::anon_obj,
load_if_immediate(bcx, additional_field_vals[i].val, load_if_immediate(bcx, additional_field_vals[i].val,
additional_field_tys[i]); additional_field_tys[i]);
let fields_ty: ty::t = ty::mk_tup(ccx.tcx, additional_field_tys); let fields_ty: ty::t = ty::mk_tup(ccx.tcx, additional_field_tys);
// Silly check
check type_is_tup_like(bcx, fields_ty);
let field = GEP_tup_like(bcx, fields_ty, body_fields.val, [0, i]); let field = GEP_tup_like(bcx, fields_ty, body_fields.val, [0, i]);
bcx = field.bcx; bcx = field.bcx;
bcx = bcx =
...@@ -356,6 +370,7 @@ fn trans_anon_obj(bcx: @block_ctxt, sp: span, anon_obj: ast::anon_obj, ...@@ -356,6 +370,7 @@ fn trans_anon_obj(bcx: @block_ctxt, sp: span, anon_obj: ast::anon_obj,
// value) wrapped in a result. // value) wrapped in a result.
let inner_obj_val: result = trans_expr(bcx, e); let inner_obj_val: result = trans_expr(bcx, e);
check type_is_tup_like(bcx, body_ty);
let body_inner_obj = let body_inner_obj =
GEP_tup_like(bcx, body_ty, body, GEP_tup_like(bcx, body_ty, body,
[0, abi::obj_body_elt_inner_obj]); [0, abi::obj_body_elt_inner_obj]);
...@@ -776,6 +791,7 @@ fn process_fwding_mthd(cx: @local_ctxt, sp: span, m: @ty::method, ...@@ -776,6 +791,7 @@ fn process_fwding_mthd(cx: @local_ctxt, sp: span, m: @ty::method,
T_ptr(type_of(cx_ccx, sp, body_ty))); T_ptr(type_of(cx_ccx, sp, body_ty)));
// Now, reach into the body and grab the inner_obj. // Now, reach into the body and grab the inner_obj.
check type_is_tup_like(bcx, body_ty);
let llinner_obj = let llinner_obj =
GEP_tup_like(bcx, body_ty, llself_obj_body, GEP_tup_like(bcx, body_ty, llself_obj_body,
[0, abi::obj_body_elt_inner_obj]); [0, abi::obj_body_elt_inner_obj]);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册