Skip to content

Commit 51fd872

Browse files
committed
---
yaml --- r: 3048 b: refs/heads/master c: 4375329 h: refs/heads/master v: v3
1 parent c55726a commit 51fd872

File tree

3 files changed

+58
-9
lines changed

3 files changed

+58
-9
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
---
2-
refs/heads/master: 8b318be4ce4381a5f7acc1864914e6ba8b0a5af2
2+
refs/heads/master: 4375329031797889e2e6f679ef484f61d2530600

trunk/src/comp/middle/trans.rs

Lines changed: 44 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2662,7 +2662,8 @@ fn get_ivec_len_and_data(&@block_ctxt bcx, ValueRef v, ty::t unit_ty) ->
26622662
[C_int(0), C_uint(abi::ivec_elt_len)]));
26632663
auto stack_elem = bcx.build.GEP(v, [C_int(0),
26642664
C_uint(abi::ivec_elt_elems)]);
2665-
stack_elem = bcx.build.PointerCast(stack_elem, T_ptr(llunitty));
2665+
stack_elem = bcx.build.PointerCast(stack_elem,
2666+
T_ptr(T_array(llunitty, 0u)));
26662667

26672668
auto on_heap = bcx.build.ICmp(lib::llvm::LLVMIntEQ, stack_len, C_int(0));
26682669

@@ -2690,21 +2691,21 @@ fn get_ivec_len_and_data(&@block_ctxt bcx, ValueRef v, ty::t unit_ty) ->
26902691
// Technically this context is unnecessary, but it makes this function
26912692
// clearer.
26922693
auto zero_len = C_int(0);
2693-
auto zero_elem = C_null(T_ptr(llunitty));
2694+
auto zero_elem = C_null(T_ptr(T_array(llunitty, 0u)));
26942695
zero_len_cx.build.Br(next_cx.llbb);
26952696

26962697
// If we're here, then we actually have a heapified vector.
26972698
auto heap_len = nonzero_len_cx.build.Load(nonzero_len_cx.build.GEP(
26982699
heap_ptr, [C_int(0), C_uint(abi::ivec_heap_elt_len)]));
26992700
auto heap_elem = nonzero_len_cx.build.GEP(heap_ptr,
2700-
[C_int(0), C_uint(abi::ivec_heap_elt_elems), C_int(0)]);
2701+
[C_int(0), C_uint(abi::ivec_heap_elt_elems)]);
27012702
nonzero_len_cx.build.Br(next_cx.llbb);
27022703

27032704
// Now we can figure out the length of `v` and get a pointer to its first
27042705
// element.
27052706
auto len = next_cx.build.Phi(T_int(), [stack_len, zero_len, heap_len],
27062707
[bcx.llbb, zero_len_cx.llbb, nonzero_len_cx.llbb]);
2707-
auto elem = next_cx.build.Phi(T_ptr(llunitty),
2708+
auto elem = next_cx.build.Phi(T_ptr(T_array(llunitty, 0u)),
27082709
[stack_elem, zero_elem, heap_elem],
27092710
[bcx.llbb, zero_len_cx.llbb, nonzero_len_cx.llbb]);
27102711
ret tup(len, elem, next_cx);
@@ -4743,8 +4744,21 @@ fn trans_field(&@block_ctxt cx, &span sp, ValueRef v, &ty::t t0,
47434744
fn trans_index(&@block_ctxt cx, &span sp, &@ast::expr base,
47444745
&@ast::expr idx, &ast::ann ann) -> lval_result {
47454746

4747+
// Is this an interior vector?
4748+
auto base_ty = ty::expr_ty(cx.fcx.lcx.ccx.tcx, base);
4749+
auto base_ty_no_boxes = ty::strip_boxes(cx.fcx.lcx.ccx.tcx, base_ty);
4750+
4751+
auto is_interior;
4752+
alt (ty::struct(cx.fcx.lcx.ccx.tcx, base_ty_no_boxes)) {
4753+
// TODO: Or-patterns
4754+
case (ty::ty_vec(_)) { is_interior = false; }
4755+
case (ty::ty_str) { is_interior = false; }
4756+
case (ty::ty_ivec(_)) { is_interior = true; }
4757+
case (ty::ty_istr) { is_interior = true; }
4758+
};
4759+
47464760
auto lv = trans_expr(cx, base);
4747-
lv = autoderef(lv.bcx, lv.val, ty::expr_ty(cx.fcx.lcx.ccx.tcx, base));
4761+
lv = autoderef(lv.bcx, lv.val, base_ty);
47484762
auto ix = trans_expr(lv.bcx, idx);
47494763
auto v = lv.val;
47504764
auto bcx = ix.bcx;
@@ -4769,8 +4783,23 @@ fn trans_index(&@block_ctxt cx, &span sp, &@ast::expr base,
47694783
auto scaled_ix = bcx.build.Mul(ix_val, unit_sz.val);
47704784
maybe_name_value(cx.fcx.lcx.ccx, scaled_ix, "scaled_ix");
47714785

4772-
auto lim = bcx.build.GEP(v, [C_int(0), C_int(abi::vec_elt_fill)]);
4773-
lim = bcx.build.Load(lim);
4786+
auto interior_len_and_data;
4787+
if (is_interior) {
4788+
auto rslt = get_ivec_len_and_data(bcx, v, unit_ty);
4789+
interior_len_and_data = some(tup(rslt._0, rslt._1));
4790+
bcx = rslt._2;
4791+
} else {
4792+
interior_len_and_data = none;
4793+
}
4794+
4795+
auto lim;
4796+
alt (interior_len_and_data) {
4797+
case (some(?lad)) { lim = lad._0; }
4798+
case (none) {
4799+
lim = bcx.build.GEP(v, [C_int(0), C_int(abi::vec_elt_fill)]);
4800+
lim = bcx.build.Load(lim);
4801+
}
4802+
}
47744803

47754804
auto bounds_check = bcx.build.ICmp(lib::llvm::LLVMIntULT,
47764805
scaled_ix, lim);
@@ -4783,7 +4812,14 @@ fn trans_index(&@block_ctxt cx, &span sp, &@ast::expr base,
47834812
auto fail_res = trans_fail(fail_cx, some[common::span](sp),
47844813
"bounds check");
47854814

4786-
auto body = next_cx.build.GEP(v, [C_int(0), C_int(abi::vec_elt_data)]);
4815+
auto body;
4816+
alt (interior_len_and_data) {
4817+
case (some(?lad)) { body = lad._1; }
4818+
case (none) {
4819+
body = next_cx.build.GEP(v, [C_int(0), C_int(abi::vec_elt_data)]);
4820+
}
4821+
}
4822+
47874823
auto elt;
47884824
if (ty::type_has_dynamic_size(cx.fcx.lcx.ccx.tcx, unit_ty)) {
47894825
body = next_cx.build.PointerCast(body, T_ptr(T_array(T_i8(), 0u)));

trunk/src/comp/middle/ty.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2789,6 +2789,19 @@ fn ret_ty_of_fn(ctxt cx, ast::ann ann) -> t {
27892789
ret ret_ty_of_fn_ty(cx, ann_to_type(cx, ann));
27902790
}
27912791

2792+
// NB: This function requires that the given type has no variables. So, inside
2793+
// typeck, you should use typeck::strip_boxes() instead.
2794+
fn strip_boxes(&ctxt cx, &ty::t t) -> ty::t {
2795+
auto t1 = t;
2796+
while (true) {
2797+
alt (struct(cx, t1)) {
2798+
case (ty::ty_box(?inner)) { t1 = inner.ty; }
2799+
case (_) { ret t1; }
2800+
}
2801+
}
2802+
fail;
2803+
}
2804+
27922805
// Local Variables:
27932806
// mode: rust
27942807
// fill-column: 78;

0 commit comments

Comments
 (0)