Skip to content

Commit f9647b5

Browse files
committed
---
yaml --- r: 10581 b: refs/heads/snap-stage3 c: 6e73e45 h: refs/heads/master i: 10579: 515fb48 v: v3
1 parent 53092d1 commit f9647b5

File tree

13 files changed

+199
-119
lines changed

13 files changed

+199
-119
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
---
22
refs/heads/master: 2898dcc5d97da9427ac367542382b6239d9c0bbf
33
refs/heads/snap-stage1: e33de59e47c5076a89eadeb38f4934f58a3618a6
4-
refs/heads/snap-stage3: 6c056fba4db7bd85a5fb3610bec6c00a7ad64f81
4+
refs/heads/snap-stage3: 6e73e45e372a0dfc5a2ebf19780dc392ec092492
55
refs/heads/try: 2898dcc5d97da9427ac367542382b6239d9c0bbf
66
refs/tags/release-0.1: 1f5c5126e96c79d22cb7862f75304136e204f105

branches/snap-stage3/src/rustc/middle/astencode.rs

Lines changed: 14 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,9 @@ import std::serialization::deserializer_helpers;
2020
import std::prettyprint::serializer;
2121
import std::smallintmap::map;
2222
import middle::{ty, typeck};
23-
import middle::typeck::{method_origin,
24-
serialize_method_origin,
25-
deserialize_method_origin,
23+
import middle::typeck::{method_origin, method_map_entry,
24+
serialize_method_map_entry,
25+
deserialize_method_map_entry,
2626
vtable_res,
2727
vtable_origin};
2828
import driver::session::session;
@@ -546,16 +546,12 @@ impl of tr for freevar_entry {
546546
}
547547

548548
// ______________________________________________________________________
549-
// Encoding and decoding of method_origin
550-
551-
fn encode_method_origin(ebml_w: ebml::writer, mo: method_origin) {
552-
serialize_method_origin(ebml_w, mo)
553-
}
549+
// Encoding and decoding of method_map_entry
554550

555551
impl helper for ebml::ebml_deserializer {
556-
fn read_method_origin(xcx: extended_decode_ctxt) -> method_origin {
557-
let fv = deserialize_method_origin(self);
558-
fv.tr(xcx)
552+
fn read_method_map_entry(xcx: extended_decode_ctxt) -> method_map_entry {
553+
let mme = deserialize_method_map_entry(self);
554+
{derefs: mme.derefs, origin: mme.origin.tr(xcx)}
559555
}
560556
}
561557

@@ -565,8 +561,8 @@ impl of tr for method_origin {
565561
typeck::method_static(did) {
566562
typeck::method_static(did.tr(xcx))
567563
}
568-
typeck::method_param(did, m, p, b) {
569-
typeck::method_param(did.tr(xcx), m, p, b)
564+
typeck::method_param(mp) {
565+
typeck::method_param({iface_id:mp.iface_id.tr(xcx) with mp})
570566
}
571567
typeck::method_iface(did, m) {
572568
typeck::method_iface(did.tr(xcx), m)
@@ -860,11 +856,11 @@ fn encode_side_tables_for_id(ecx: @e::encode_ctxt,
860856
// impl_map is not used except when emitting metadata,
861857
// don't need to keep it.
862858

863-
option::iter(maps.method_map.find(id)) {|mo|
859+
option::iter(maps.method_map.find(id)) {|mme|
864860
ebml_w.tag(c::tag_table_method_map) {||
865861
ebml_w.id(id);
866862
ebml_w.tag(c::tag_table_val) {||
867-
serialize_method_origin(ebml_w, mo)
863+
serialize_method_map_entry(ebml_w, mme)
868864
}
869865
}
870866
}
@@ -983,8 +979,9 @@ fn decode_side_tables(xcx: extended_decode_ctxt,
983979
let dvec = @dvec::from_vec(vec::to_mut(ids));
984980
dcx.maps.last_use_map.insert(id, dvec);
985981
} else if tag == (c::tag_table_method_map as uint) {
986-
dcx.maps.method_map.insert(id,
987-
val_dsr.read_method_origin(xcx));
982+
dcx.maps.method_map.insert(
983+
id,
984+
val_dsr.read_method_map_entry(xcx));
988985
} else if tag == (c::tag_table_vtable_map as uint) {
989986
dcx.maps.vtable_map.insert(id,
990987
val_dsr.read_vtable_res(xcx));

branches/snap-stage3/src/rustc/middle/kind.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -261,14 +261,15 @@ fn check_expr(e: @expr, cx: ctx, v: visit::vt<ctx>) {
261261
ty::lookup_item_type(cx.tcx, did).bounds
262262
}
263263
expr_field(base, _, _) {
264-
alt cx.method_map.get(e.id) {
264+
alt cx.method_map.get(e.id).origin {
265265
typeck::method_static(did) {
266266
// n.b.: When we encode class/impl methods, the bounds
267267
// that we encode include both the class/impl bounds
268268
// and then the method bounds themselves...
269269
ty::lookup_item_type(cx.tcx, did).bounds
270270
}
271-
typeck::method_param(ifce_id, n_mth, _, _) |
271+
typeck::method_param({iface_id:ifce_id,
272+
method_num:n_mth, _}) |
272273
typeck::method_iface(ifce_id, n_mth) {
273274
// ...iface methods bounds, in contrast, include only the
274275
// method bounds, so we must preprend the tps from the

branches/snap-stage3/src/rustc/middle/trans/base.rs

Lines changed: 101 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -1517,13 +1517,13 @@ fn trans_unary(bcx: block, op: ast::unop, e: @ast::expr,
15171517
let _icx = bcx.insn_ctxt("trans_unary");
15181518
// Check for user-defined method call
15191519
alt bcx.ccx().maps.method_map.find(un_expr.id) {
1520-
some(origin) {
1520+
some(mentry) {
15211521
let callee_id = ast_util::op_expr_callee_id(un_expr);
15221522
let fty = node_id_type(bcx, callee_id);
15231523
ret trans_call_inner(
15241524
bcx, un_expr.info(), fty,
15251525
expr_ty(bcx, un_expr),
1526-
{|bcx| impl::trans_method_callee(bcx, callee_id, e, origin) },
1526+
{|bcx| impl::trans_method_callee(bcx, callee_id, e, mentry) },
15271527
arg_exprs([]), dest);
15281528
}
15291529
_ {}
@@ -1814,14 +1814,17 @@ fn root_value(bcx: block, val: ValueRef, ty: ty::t,
18141814
add_root_cleanup(bcx, scope_id, root_loc, ty);
18151815
}
18161816

1817+
// autoderefs the value `v`, either as many times as we can (if `max ==
1818+
// uint::max_value`) or `max` times.
18171819
fn autoderef(cx: block, e_id: ast::node_id,
1818-
v: ValueRef, t: ty::t) -> result_t {
1820+
v: ValueRef, t: ty::t,
1821+
max: uint) -> result_t {
18191822
let _icx = cx.insn_ctxt("autoderef");
18201823
let mut v1: ValueRef = v;
18211824
let mut t1: ty::t = t;
18221825
let ccx = cx.ccx();
18231826
let mut derefs = 0u;
1824-
loop {
1827+
while derefs < max {
18251828
#debug["autoderef(e_id=%d, v1=%s, t1=%s, derefs=%u)",
18261829
e_id, val_str(ccx.tn, v1), ty_to_str(ccx.tcx, t1),
18271830
derefs];
@@ -1872,6 +1875,11 @@ fn autoderef(cx: block, e_id: ast::node_id,
18721875
}
18731876
v1 = load_if_immediate(cx, v1, t1);
18741877
}
1878+
1879+
// either we were asked to deref a specific number of times, in which case
1880+
// we should have, or we asked to deref as many times as we can
1881+
assert derefs == max || max == uint::max_value;
1882+
18751883
ret {bcx: cx, val: v1, ty: t1};
18761884
}
18771885

@@ -2572,7 +2580,9 @@ fn trans_rec_field(bcx: block, base: @ast::expr,
25722580
field: ast::ident) -> lval_result {
25732581
let _icx = bcx.insn_ctxt("trans_rec_field");
25742582
let {bcx, val} = trans_temp_expr(bcx, base);
2575-
let {bcx, val, ty} = autoderef(bcx, base.id, val, expr_ty(bcx, base));
2583+
let {bcx, val, ty} =
2584+
autoderef(bcx, base.id, val, expr_ty(bcx, base),
2585+
uint::max_value);
25762586
trans_rec_field_inner(bcx, val, ty, field, base.span)
25772587
}
25782588

@@ -2611,7 +2621,7 @@ fn trans_index(cx: block, ex: @ast::expr, base: @ast::expr,
26112621
let _icx = cx.insn_ctxt("trans_index");
26122622
let base_ty = expr_ty(cx, base);
26132623
let exp = trans_temp_expr(cx, base);
2614-
let lv = autoderef(exp.bcx, base.id, exp.val, base_ty);
2624+
let lv = autoderef(exp.bcx, base.id, exp.val, base_ty, uint::max_value);
26152625
let ix = trans_temp_expr(lv.bcx, idx);
26162626
let v = lv.val;
26172627
let bcx = ix.bcx;
@@ -2921,13 +2931,16 @@ fn trans_loop_body(bcx: block, e: @ast::expr, ret_flag: option<ValueRef>,
29212931
// temp_cleanups: cleanups that should run only if failure occurs before the
29222932
// call takes place:
29232933
fn trans_arg_expr(cx: block, arg: ty::arg, lldestty: TypeRef, e: @ast::expr,
2924-
&temp_cleanups: [ValueRef], ret_flag: option<ValueRef>)
2934+
&temp_cleanups: [ValueRef], ret_flag: option<ValueRef>,
2935+
derefs: uint)
29252936
-> result {
29262937
#debug("+++ trans_arg_expr on %s", expr_to_str(e));
29272938
let _icx = cx.insn_ctxt("trans_arg_expr");
29282939
let ccx = cx.ccx();
29292940
let e_ty = expr_ty(cx, e);
29302941
let is_bot = ty::type_is_bot(e_ty);
2942+
2943+
// translate the arg expr as an lvalue
29312944
let lv = alt ret_flag {
29322945
// If there is a ret_flag, this *must* be a loop body
29332946
some(ptr) {
@@ -2939,93 +2952,111 @@ fn trans_arg_expr(cx: block, arg: ty::arg, lldestty: TypeRef, e: @ast::expr,
29392952
}
29402953
}
29412954
}
2942-
none { trans_temp_lval(cx, e) }
2955+
none {
2956+
trans_temp_lval(cx, e)
2957+
}
29432958
};
2959+
2960+
// auto-deref value as required (this only applies to method
2961+
// call receivers) of method
2962+
#debug(" pre-deref value: %s", val_str(lv.bcx.ccx().tn, lv.val));
2963+
let {lv, e_ty} = if derefs == 0u {
2964+
{lv: lv, e_ty: e_ty}
2965+
} else {
2966+
let {bcx, val} = lval_result_to_result(lv, e_ty);
2967+
let {bcx, val, ty: e_ty} =
2968+
autoderef(bcx, e.id, val, e_ty, derefs);
2969+
{lv: {bcx: bcx, val: val, kind: temporary},
2970+
e_ty: e_ty}
2971+
};
2972+
2973+
// borrow value (convert from @T to &T and so forth)
29442974
#debug(" pre-adaptation value: %s", val_str(lv.bcx.ccx().tn, lv.val));
2945-
let {lv, arg} = adapt_borrowed_value(lv, arg, e);
2975+
let {lv, ty: e_ty} = adapt_borrowed_value(lv, e, e_ty);
29462976
let mut bcx = lv.bcx;
29472977
let mut val = lv.val;
29482978
#debug(" adapted value: %s", val_str(bcx.ccx().tn, val));
2979+
2980+
// finally, deal with the various modes
29492981
let arg_mode = ty::resolved_mode(ccx.tcx, arg.mode);
29502982
if is_bot {
29512983
// For values of type _|_, we generate an
29522984
// "undef" value, as such a value should never
29532985
// be inspected. It's important for the value
29542986
// to have type lldestty (the callee's expected type).
29552987
val = llvm::LLVMGetUndef(lldestty);
2956-
} else if arg_mode == ast::by_ref || arg_mode == ast::by_val {
2957-
let imm = ty::type_is_immediate(arg.ty);
2958-
#debug[" arg.ty=%s, imm=%b, arg_mode=%?, lv.kind=%?",
2959-
ty_to_str(bcx.tcx(), arg.ty), imm, arg_mode, lv.kind];
2960-
if arg_mode == ast::by_ref && lv.kind != owned && imm {
2961-
val = do_spill_noroot(bcx, val);
2962-
}
2963-
if arg_mode == ast::by_val && (lv.kind == owned || !imm) {
2964-
val = Load(bcx, val);
2965-
}
2966-
} else if arg_mode == ast::by_copy || arg_mode == ast::by_move {
2967-
let alloc = alloc_ty(bcx, arg.ty);
2968-
let move_out = arg_mode == ast::by_move ||
2969-
ccx.maps.last_use_map.contains_key(e.id);
2970-
if lv.kind == temporary { revoke_clean(bcx, val); }
2971-
if lv.kind == owned || !ty::type_is_immediate(arg.ty) {
2972-
memmove_ty(bcx, alloc, val, arg.ty);
2973-
if move_out && ty::type_needs_drop(ccx.tcx, arg.ty) {
2974-
bcx = zero_mem(bcx, val, arg.ty);
2988+
} else {
2989+
alt arg_mode {
2990+
ast::by_ref | ast::by_mutbl_ref {
2991+
// Ensure that the value is spilled into memory:
2992+
if lv.kind != owned && ty::type_is_immediate(e_ty) {
2993+
val = do_spill_noroot(bcx, val);
29752994
}
2976-
} else { Store(bcx, val, alloc); }
2977-
val = alloc;
2978-
if lv.kind != temporary && !move_out {
2979-
bcx = take_ty(bcx, val, arg.ty);
2980-
}
2995+
}
2996+
2997+
ast::by_val {
2998+
// Ensure that the value is not spilled into memory:
2999+
if lv.kind == owned || !ty::type_is_immediate(e_ty) {
3000+
val = Load(bcx, val);
3001+
}
3002+
}
29813003

2982-
// In the event that failure occurs before the call actually
2983-
// happens, have to cleanup this copy:
2984-
add_clean_temp_mem(bcx, val, arg.ty);
2985-
temp_cleanups += [val];
2986-
} else if ty::type_is_immediate(arg.ty) && lv.kind != owned {
2987-
val = do_spill(bcx, val, arg.ty);
3004+
ast::by_copy | ast::by_move {
3005+
// Ensure that an owned copy of the value is in memory:
3006+
let alloc = alloc_ty(bcx, arg.ty);
3007+
let move_out = arg_mode == ast::by_move ||
3008+
ccx.maps.last_use_map.contains_key(e.id);
3009+
if lv.kind == temporary { revoke_clean(bcx, val); }
3010+
if lv.kind == owned || !ty::type_is_immediate(arg.ty) {
3011+
memmove_ty(bcx, alloc, val, arg.ty);
3012+
if move_out && ty::type_needs_drop(ccx.tcx, arg.ty) {
3013+
bcx = zero_mem(bcx, val, arg.ty);
3014+
}
3015+
} else { Store(bcx, val, alloc); }
3016+
val = alloc;
3017+
if lv.kind != temporary && !move_out {
3018+
bcx = take_ty(bcx, val, arg.ty);
3019+
}
3020+
3021+
// In the event that failure occurs before the call actually
3022+
// happens, have to cleanup this copy:
3023+
add_clean_temp_mem(bcx, val, arg.ty);
3024+
temp_cleanups += [val];
3025+
}
3026+
}
29883027
}
29893028

29903029
if !is_bot && arg.ty != e_ty || ty::type_has_params(arg.ty) {
29913030
#debug(" casting from %s", val_str(bcx.ccx().tn, val));
29923031
val = PointerCast(bcx, val, lldestty);
29933032
}
3033+
29943034
#debug("--- trans_arg_expr passing %s", val_str(bcx.ccx().tn, val));
29953035
ret rslt(bcx, val);
29963036
}
29973037

2998-
fn load_value_from_lval_result(lv: lval_result) -> ValueRef {
2999-
alt lv.kind {
3000-
temporary { lv.val }
3001-
owned { Load(lv.bcx, lv.val) }
3002-
owned_imm { lv.val }
3003-
}
3004-
}
3005-
30063038
// when invoking a method, an argument of type @T or ~T can be implicltly
30073039
// converted to an argument of type &T. Similarly, [T] can be converted to
30083040
// [T]/& and so on. If such a conversion (called borrowing) is necessary,
30093041
// then the borrowings table will have an appropriate entry inserted. This
30103042
// routine consults this table and performs these adaptations. It returns a
30113043
// new location for the borrowed result as well as a new type for the argument
30123044
// that reflects the borrowed value and not the original.
3013-
fn adapt_borrowed_value(lv: lval_result, arg: ty::arg,
3014-
e: @ast::expr) -> {lv: lval_result,
3015-
arg: ty::arg} {
3045+
fn adapt_borrowed_value(lv: lval_result,
3046+
e: @ast::expr,
3047+
e_ty: ty::t) -> {lv: lval_result,
3048+
ty: ty::t} {
30163049
let bcx = lv.bcx;
30173050
if !expr_is_borrowed(bcx, e) {
3018-
ret {lv:lv, arg:arg};
3051+
ret {lv:lv, ty:e_ty};
30193052
}
30203053

3021-
let e_ty = expr_ty(bcx, e);
30223054
alt ty::get(e_ty).struct {
30233055
ty::ty_uniq(mt) | ty::ty_box(mt) {
3024-
let box_ptr = load_value_from_lval_result(lv);
3056+
let box_ptr = load_value_from_lval_result(lv, e_ty);
30253057
let body_ptr = GEPi(bcx, box_ptr, [0u, abi::box_field_body]);
30263058
let rptr_ty = ty::mk_rptr(bcx.tcx(), ty::re_static, mt);
3027-
ret {lv: lval_temp(bcx, body_ptr),
3028-
arg: {ty: rptr_ty with arg}};
3059+
ret {lv: lval_temp(bcx, body_ptr), ty: rptr_ty};
30293060
}
30303061

30313062
ty::ty_str | ty::ty_vec(_) |
@@ -3057,8 +3088,7 @@ fn adapt_borrowed_value(lv: lval_result, arg: ty::arg,
30573088
{ty: unit_ty, mutbl: ast::m_imm},
30583089
ty::vstore_slice(ty::re_static));
30593090

3060-
ret {lv: lval_temp(bcx, p),
3061-
arg: {ty: slice_ty with arg}};
3091+
ret {lv: lval_temp(bcx, p), ty: slice_ty};
30623092
}
30633093

30643094
_ {
@@ -3120,7 +3150,7 @@ fn trans_args(cx: block, llenv: ValueRef, args: call_args, fn_ty: ty::t,
31203150
vec::iteri(es) {|i, e|
31213151
let r = trans_arg_expr(bcx, arg_tys[i], llarg_tys[i],
31223152
e, temp_cleanups, if i == last { ret_flag }
3123-
else { none });
3153+
else { none }, 0u);
31243154
bcx = r.bcx;
31253155
llargs += [r.val];
31263156
}
@@ -3494,11 +3524,20 @@ fn trans_temp_lval(bcx: block, e: @ast::expr) -> lval_result {
34943524
// expressions that must 'end up somewhere' (or get ignored).
34953525
fn trans_temp_expr(bcx: block, e: @ast::expr) -> result {
34963526
let _icx = bcx.insn_ctxt("trans_temp_expr");
3497-
let mut {bcx, val, kind} = trans_temp_lval(bcx, e);
3498-
if kind == owned {
3499-
val = load_if_immediate(bcx, val, expr_ty(bcx, e));
3527+
lval_result_to_result(trans_temp_lval(bcx, e), expr_ty(bcx, e))
3528+
}
3529+
3530+
fn load_value_from_lval_result(lv: lval_result, ty: ty::t) -> ValueRef {
3531+
alt lv.kind {
3532+
temporary { lv.val }
3533+
owned { load_if_immediate(lv.bcx, lv.val, ty) }
3534+
owned_imm { lv.val }
35003535
}
3501-
ret {bcx: bcx, val: val};
3536+
}
3537+
3538+
fn lval_result_to_result(lv: lval_result, ty: ty::t) -> result {
3539+
let val = load_value_from_lval_result(lv, ty);
3540+
{bcx: lv.bcx, val: val}
35023541
}
35033542

35043543
// Arranges for the value found in `*root_loc` to be dropped once the scope

0 commit comments

Comments
 (0)