Skip to content

Commit d170d32

Browse files
committed
---
yaml --- r: 734 b: refs/heads/master c: 62c224f h: refs/heads/master v: v3
1 parent d9afd5c commit d170d32

File tree

8 files changed

+157
-91
lines changed

8 files changed

+157
-91
lines changed

[refs]

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
---
2-
refs/heads/master: f6e3e6903b20df01a6abe36d741c39d6e9696ebb
2+
refs/heads/master: 62c224ffe4845ed3a1f651d05ea0be84d5c870ea

trunk/src/Makefile

+1
Original file line numberDiff line numberDiff line change
@@ -462,6 +462,7 @@ TEST_XFAILS_LLVM := $(TASK_XFAILS) \
462462
deep.rs \
463463
deref.rs \
464464
destructor-ordering.rs \
465+
drop-on-empty-block-exit.rs \
465466
export-non-interference.rs \
466467
exterior.rs \
467468
fn-lval.rs \

trunk/src/boot/fe/ast.ml

+1
Original file line numberDiff line numberDiff line change
@@ -1545,6 +1545,7 @@ and fmt_pat (ff:Format.formatter) (pat:pat) : unit =
15451545
fmt_lval ff ctor;
15461546
fmt_bracketed_arr_sep "(" ")" "," fmt_pat ff pats
15471547
| PAT_slot (_, ident) ->
1548+
fmt ff "?";
15481549
fmt_ident ff ident
15491550
| PAT_wild ->
15501551
fmt ff "_"

trunk/src/boot/me/loop.ml

+2
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,8 @@ let loop_depth_visitor
114114
let visit_block_pre b =
115115
if Hashtbl.mem cx.ctxt_block_is_loop_body b.id
116116
then push_loop ();
117+
let fcx = Stack.top fcxs in
118+
htab_put cx.ctxt_block_loop_depths b.id fcx.current_depth;
117119
inner.Walk.visit_block_pre b
118120
in
119121

trunk/src/boot/me/semant.ml

+8
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,7 @@ type ctxt =
131131
(* Typestate-y stuff. *)
132132
ctxt_stmt_is_init: (node_id,unit) Hashtbl.t;
133133
ctxt_post_stmt_slot_drops: (node_id,node_id list) Hashtbl.t;
134+
ctxt_post_block_slot_drops: (node_id,node_id list) Hashtbl.t;
134135

135136
(* Layout-y stuff. *)
136137
ctxt_slot_aliased: (node_id,unit) Hashtbl.t;
@@ -141,6 +142,7 @@ type ctxt =
141142
ctxt_call_sizes: (node_id,size) Hashtbl.t;
142143
ctxt_block_is_loop_body: (node_id,unit) Hashtbl.t;
143144
ctxt_stmt_loop_depths: (node_id,int) Hashtbl.t;
145+
ctxt_block_loop_depths: (node_id,int) Hashtbl.t;
144146
ctxt_slot_loop_depths: (node_id,int) Hashtbl.t;
145147

146148
(* Translation-y stuff. *)
@@ -216,6 +218,7 @@ let new_ctxt sess abi crate =
216218

217219
ctxt_stmt_is_init = Hashtbl.create 0;
218220
ctxt_post_stmt_slot_drops = Hashtbl.create 0;
221+
ctxt_post_block_slot_drops = Hashtbl.create 0;
219222

220223
ctxt_slot_aliased = Hashtbl.create 0;
221224
ctxt_slot_is_obj_state = Hashtbl.create 0;
@@ -227,6 +230,7 @@ let new_ctxt sess abi crate =
227230
ctxt_block_is_loop_body = Hashtbl.create 0;
228231
ctxt_slot_loop_depths = Hashtbl.create 0;
229232
ctxt_stmt_loop_depths = Hashtbl.create 0;
233+
ctxt_block_loop_depths = Hashtbl.create 0;
230234

231235
ctxt_fn_fixups = Hashtbl.create 0;
232236
ctxt_block_fixups = Hashtbl.create 0;
@@ -399,6 +403,10 @@ let get_stmt_depth (cx:ctxt) (id:node_id) : int =
399403
Hashtbl.find cx.ctxt_stmt_loop_depths id
400404
;;
401405

406+
let get_block_depth (cx:ctxt) (id:node_id) : int =
407+
Hashtbl.find cx.ctxt_block_loop_depths id
408+
;;
409+
402410
let get_slot_depth (cx:ctxt) (id:node_id) : int =
403411
Hashtbl.find cx.ctxt_slot_loop_depths id
404412
;;

trunk/src/boot/me/trans.ml

+73-37
Original file line numberDiff line numberDiff line change
@@ -826,10 +826,51 @@ let trans_visitor
826826
out diff current_fp
827827
in
828828

829+
let curr_stmt_depth _ =
830+
if (Stack.is_empty curr_stmt)
831+
then None
832+
else
833+
Some
834+
(get_stmt_depth cx (Stack.top curr_stmt))
835+
in
836+
829837
let cell_of_block_slot
838+
?access_depth:(access_depth=curr_stmt_depth())
830839
(slot_id:node_id)
831840
: Il.cell =
841+
832842
let referent_type = slot_id_referent_type slot_id in
843+
844+
let local_access off =
845+
Il.Mem (fp_off_sz off, referent_type)
846+
in
847+
848+
let outer_access off slot_depth depth =
849+
let _ = assert (slot_depth < depth) in
850+
let _ =
851+
iflog
852+
begin
853+
fun _ ->
854+
let k =
855+
Hashtbl.find cx.ctxt_slot_keys slot_id
856+
in
857+
annotate (Printf.sprintf
858+
"access outer frame slot #%d = %s"
859+
(int_of_node slot_id)
860+
(Fmt.fmt_to_str Ast.fmt_slot_key k))
861+
end
862+
in
863+
let diff = depth - slot_depth in
864+
let _ = annotate "get outer frame pointer" in
865+
let fp = get_nth_outer_frame_ptr diff in
866+
let _ = annotate "calculate size" in
867+
let p =
868+
based_sz (get_ty_params_of_current_frame())
869+
(fst (force_to_reg (Il.Cell fp))) off
870+
in
871+
Il.Mem (p, referent_type)
872+
in
873+
833874
match htab_search cx.ctxt_slot_vregs slot_id with
834875
Some vr ->
835876
begin
@@ -865,43 +906,15 @@ let trans_visitor
865906
Il.Mem (slot_mem, referent_type)
866907
end
867908
else
868-
if (Stack.is_empty curr_stmt)
869-
then
870-
Il.Mem (fp_off_sz off, referent_type)
871-
else
872-
let slot_depth = get_slot_depth cx slot_id in
873-
let stmt_depth =
874-
get_stmt_depth cx (Stack.top curr_stmt)
875-
in
876-
if slot_depth <> stmt_depth
877-
then
878-
let _ = assert (slot_depth < stmt_depth) in
879-
let _ =
880-
iflog
881-
begin
882-
fun _ ->
883-
let k =
884-
Hashtbl.find cx.ctxt_slot_keys slot_id
885-
in
886-
annotate
887-
(Printf.sprintf
888-
"access outer frame slot #%d = %s"
889-
(int_of_node slot_id)
890-
(Fmt.fmt_to_str
891-
Ast.fmt_slot_key k))
892-
end
893-
in
894-
let diff = stmt_depth - slot_depth in
895-
let _ = annotate "get outer frame pointer" in
896-
let fp = get_nth_outer_frame_ptr diff in
897-
let _ = annotate "calculate size" in
898-
let p =
899-
based_sz (get_ty_params_of_current_frame())
900-
(fst (force_to_reg (Il.Cell fp))) off
901-
in
902-
Il.Mem (p, referent_type)
903-
else
904-
Il.Mem (fp_off_sz off, referent_type)
909+
match access_depth with
910+
None -> local_access off
911+
| Some depth ->
912+
let slot_depth = get_slot_depth cx slot_id in
913+
if slot_depth <> depth
914+
then
915+
outer_access off slot_depth depth
916+
else
917+
local_access off
905918
end
906919
in
907920

@@ -2434,12 +2447,35 @@ let trans_visitor
24342447
| Ast.EXPR_atom a ->
24352448
trans_atom a
24362449

2450+
and drop_slots_after_block bid : unit =
2451+
match htab_search cx.ctxt_post_block_slot_drops bid with
2452+
None -> ()
2453+
| Some slots ->
2454+
List.iter
2455+
begin
2456+
fun slot_id ->
2457+
let slot = get_slot cx slot_id in
2458+
let k = Hashtbl.find cx.ctxt_slot_keys slot_id in
2459+
let depth = Hashtbl.find cx.ctxt_block_loop_depths bid in
2460+
iflog (fun _ ->
2461+
annotate
2462+
(Printf.sprintf
2463+
"post-block, drop_slot %d = %s "
2464+
(int_of_node slot_id)
2465+
(Fmt.fmt_to_str Ast.fmt_slot_key k)));
2466+
drop_slot_in_current_frame
2467+
(cell_of_block_slot
2468+
~access_depth:(Some depth) slot_id) slot
2469+
end
2470+
slots
2471+
24372472
and trans_block (block:Ast.block) : unit =
24382473
flush_emitter_size_cache();
24392474
trace_str cx.ctxt_sess.Session.sess_trace_block
24402475
"entering block";
24412476
emit (Il.Enter (Hashtbl.find cx.ctxt_block_fixups block.id));
24422477
Array.iter trans_stmt block.node;
2478+
drop_slots_after_block block.id;
24432479
trace_str cx.ctxt_sess.Session.sess_trace_block
24442480
"exiting block";
24452481
emit Il.Leave;

trunk/src/boot/me/typestate.ml

+60-53
Original file line numberDiff line numberDiff line change
@@ -449,9 +449,12 @@ type slots_stack = node_id Stack.t;;
449449
type block_slots_stack = slots_stack Stack.t;;
450450
type frame_block_slots_stack = block_slots_stack Stack.t;;
451451
type loop_block_slots_stack = block_slots_stack option Stack.t;;
452-
(* like ret drops slots from all blocks in the frame
453-
* break from a simple loo drops slots from all block in a loop *)
454-
let (loop_blocks:loop_block_slots_stack) =
452+
453+
(* Like ret drops slots from all blocks in the frame
454+
* break from a simple loop drops slots from all block in a loop
455+
*)
456+
457+
let (loop_blocks:loop_block_slots_stack) =
455458
let s = Stack.create() in Stack.push None s; s
456459

457460
let condition_assigning_visitor
@@ -583,7 +586,7 @@ let condition_assigning_visitor
583586
let precond = slot_inits (lval_slots cx lval) in
584587
raise_precondition sid precond;
585588
in
586-
589+
587590
let visit_stmt_pre s =
588591
begin
589592
match s.node with
@@ -1317,11 +1320,12 @@ let lifecycle_visitor
13171320

13181321

13191322
let visit_block_pre b =
1320-
1323+
13211324
let s = Stack.create() in
13221325
begin
1323-
match Stack.top loop_blocks with
1324-
Some loop -> Stack.push s loop | None -> ()
1326+
match Stack.top loop_blocks with
1327+
Some loop -> Stack.push s loop
1328+
| None -> ()
13251329
end;
13261330
Stack.push s (Stack.top frame_blocks);
13271331
begin
@@ -1337,7 +1341,7 @@ let lifecycle_visitor
13371341
inner.Walk.visit_block_pre b
13381342
in
13391343

1340-
let note_drops stmt slots =
1344+
let note_stmt_drops stmt slots =
13411345
iflog cx
13421346
begin
13431347
fun _ ->
@@ -1352,6 +1356,21 @@ let lifecycle_visitor
13521356
htab_put cx.ctxt_post_stmt_slot_drops stmt.id slots
13531357
in
13541358

1359+
let note_block_drops bid slots =
1360+
iflog cx
1361+
begin
1362+
fun _ ->
1363+
log cx "implicit drop of %d slots after block %d: "
1364+
(List.length slots)
1365+
(int_of_node bid);
1366+
List.iter (fun s -> log cx "drop: %a"
1367+
Ast.sprintf_slot_key
1368+
(Hashtbl.find cx.ctxt_slot_keys s))
1369+
slots
1370+
end;
1371+
htab_put cx.ctxt_post_block_slot_drops bid slots
1372+
in
1373+
13551374
let filter_live_block_slots slots =
13561375
List.filter (fun i -> Hashtbl.mem live_block_slots i) slots
13571376
in
@@ -1360,37 +1379,24 @@ let lifecycle_visitor
13601379
inner.Walk.visit_block_post b;
13611380
begin
13621381
match Stack.top loop_blocks with
1363-
Some loop ->
1364-
ignore(Stack.pop loop);
1365-
if Stack.is_empty loop then
1366-
ignore(Stack.pop loop_blocks);
1382+
Some loop ->
1383+
ignore (Stack.pop loop);
1384+
if Stack.is_empty loop
1385+
then ignore (Stack.pop loop_blocks);
13671386
| None -> ()
13681387
end;
13691388
let block_slots = Stack.pop (Stack.top frame_blocks) in
1370-
let stmts = b.node in
1371-
let len = Array.length stmts in
1372-
if len > 0
1373-
then
1374-
begin
1375-
let s = stmts.(len-1) in
1376-
match s.node with
1377-
Ast.STMT_ret _
1378-
| Ast.STMT_be _
1379-
| Ast.STMT_break ->
1380-
() (* Taken care of in visit_stmt_post below. *)
1381-
| _ ->
1382-
(* The blk_slots stack we have has accumulated slots in
1383-
* declaration order as we walked the block; the top of the
1384-
* stack is the last-declared slot. We want to generate
1385-
* slot-drop obligations here for the slots in top-down order
1386-
* (starting with the last-declared) but only hitting those
1387-
* slots that actually got initialized (went live) at some
1388-
* point in the block.
1389-
*)
1390-
let slots = stk_elts_from_top block_slots in
1391-
let live = filter_live_block_slots slots in
1392-
note_drops s live
1393-
end;
1389+
(* The blk_slots stack we have has accumulated slots in
1390+
* declaration order as we walked the block; the top of the
1391+
* stack is the last-declared slot. We want to generate
1392+
* slot-drop obligations here for the slots in top-down order
1393+
* (starting with the last-declared) but only hitting those
1394+
* slots that actually got initialized (went live) at some
1395+
* point in the block.
1396+
*)
1397+
let slots = stk_elts_from_top block_slots in
1398+
let live = filter_live_block_slots slots in
1399+
note_block_drops b.id live
13941400
in
13951401

13961402
let visit_stmt_pre s =
@@ -1499,33 +1505,34 @@ let lifecycle_visitor
14991505

15001506
let visit_stmt_post s =
15011507
inner.Walk.visit_stmt_post s;
1502-
let handle_ret_like_stmt block_stack =
1508+
1509+
let handle_outward_jump_stmt block_stack =
15031510
let blocks = stk_elts_from_top block_stack in
15041511
let slots = List.concat (List.map stk_elts_from_top blocks) in
15051512
let live = filter_live_block_slots slots in
1506-
note_drops s live
1513+
note_stmt_drops s live
15071514
in
1508-
match s.node with
1509-
Ast.STMT_ret _
1510-
| Ast.STMT_be _ ->
1511-
handle_ret_like_stmt (Stack.top frame_blocks)
1512-
| Ast.STMT_break ->
1513-
begin
1514-
match (Stack.top loop_blocks) with
1515-
Some loop -> handle_ret_like_stmt loop
1516-
| None ->
1517-
iflog cx (fun _ ->
1518-
log cx "break statement outside of a loop");
1519-
err (Some s.id) "break statement outside of a loop"
1520-
end
1521-
| _ -> ()
1515+
1516+
match s.node with
1517+
Ast.STMT_ret _
1518+
| Ast.STMT_be _ ->
1519+
handle_outward_jump_stmt (Stack.top frame_blocks)
1520+
1521+
| Ast.STMT_break ->
1522+
begin
1523+
match (Stack.top loop_blocks) with
1524+
Some loop -> handle_outward_jump_stmt loop
1525+
| None ->
1526+
err (Some s.id) "break statement outside of a loop"
1527+
end
1528+
| _ -> ()
15221529
in
15231530

15241531
let enter_frame _ =
15251532
Stack.push (Stack.create()) frame_blocks;
15261533
Stack.push None loop_blocks
15271534
in
1528-
1535+
15291536
let leave_frame _ =
15301537
ignore (Stack.pop frame_blocks);
15311538
match Stack.pop loop_blocks with

0 commit comments

Comments
 (0)