Skip to content

Commit 2b8915f

Browse files
committed
even more exception handling mess
1 parent 5a2090d commit 2b8915f

File tree

1 file changed

+30
-29
lines changed

1 file changed

+30
-29
lines changed

src/optimization/analyzerTexprTransformer.ml

Lines changed: 30 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -784,6 +784,14 @@ and block_to_texpr_coroutine ctx bb vcontinuation vresult verror p =
784784
fun () -> (let id = !counter in incr counter; id)
785785
in
786786

787+
let get_rethrow_state_id =
788+
let rethrow_state_id = ref (-1) in
789+
fun () -> begin
790+
if !rethrow_state_id = (-1) then rethrow_state_id := get_next_state_id ();
791+
!rethrow_state_id;
792+
end
793+
in
794+
787795
let mk_continuation_call eresult p =
788796
let econtinuation = make_local vcontinuation p in
789797
mk (TCall (econtinuation, [eresult; make_null t_dynamic p])) com.basic.tvoid p
@@ -837,7 +845,7 @@ and block_to_texpr_coroutine ctx bb vcontinuation vresult verror p =
837845

838846
(* TODO: maybe merge this into block_to_texpr somehow, and only introduce new states when there is a suspension point *)
839847
print_endline "---";
840-
let rec loop bb state_id back_state_id current_el while_loop =
848+
let rec loop bb state_id back_state_id current_el while_loop exc_state_id_getter =
841849
let p = bb.bb_pos in
842850
(* TODO: only do this in the end, avoid unnecessary List.rev *)
843851
let el = DynArray.to_list bb.bb_el in
@@ -853,7 +861,7 @@ and block_to_texpr_coroutine ctx bb vcontinuation vresult verror p =
853861
| SESuspend (call, bb_next) ->
854862
let next_state_id = get_next_state_id () in
855863
print_endline (Printf.sprintf "suspend cur:%d,next:%d,back:%d" state_id next_state_id back_state_id);
856-
loop bb_next next_state_id back_state_id [] while_loop;
864+
loop bb_next next_state_id back_state_id [] while_loop exc_state_id_getter;
857865
let ecallcoroutine = mk_suspending_call call in
858866
let esetstate = set_state next_state_id in
859867
add_state (current_el @ el @ [esetstate; ecallcoroutine; ereturn])
@@ -891,23 +899,23 @@ and block_to_texpr_coroutine ctx bb vcontinuation vresult verror p =
891899

892900
| SEMerge bb_next ->
893901
print_endline (Printf.sprintf "merge cur:%d,back:%d" state_id back_state_id);
894-
loop bb_next state_id back_state_id (current_el @ el) while_loop
902+
loop bb_next state_id back_state_id (current_el @ el) while_loop exc_state_id_getter
895903

896904
| SESubBlock (bb_sub,bb_next) ->
897905
let sub_state_id = get_next_state_id () in
898906
let next_state_id = get_next_state_id () in
899907
print_endline (Printf.sprintf "sub cur:%d,sub:%d,next:%d,back:%d" state_id sub_state_id next_state_id back_state_id);
900-
loop bb_next next_state_id back_state_id [] while_loop;
901-
loop bb_sub sub_state_id next_state_id [] while_loop;
908+
loop bb_next next_state_id back_state_id [] while_loop exc_state_id_getter;
909+
loop bb_sub sub_state_id next_state_id [] while_loop exc_state_id_getter;
902910
add_state (current_el @ el @ [set_state sub_state_id])
903911

904912
| SEIfThen (bb_then,bb_next,p) ->
905913
let econd = get_cond_branch () in
906914
let then_state_id = get_next_state_id () in
907915
let next_state_id = get_next_state_id () in
908916
print_endline (Printf.sprintf "if-then cur:%d,then:%d,next:%d,back:%d" state_id then_state_id next_state_id back_state_id);
909-
loop bb_then then_state_id next_state_id [] while_loop;
910-
loop bb_next next_state_id back_state_id [] while_loop;
917+
loop bb_then then_state_id next_state_id [] while_loop exc_state_id_getter;
918+
loop bb_next next_state_id back_state_id [] while_loop exc_state_id_getter;
911919
let eif = mk (TIf (econd, set_state then_state_id, Some (set_state next_state_id))) com.basic.tint p in
912920
add_state (current_el @ el @ [eif])
913921

@@ -917,9 +925,9 @@ and block_to_texpr_coroutine ctx bb vcontinuation vresult verror p =
917925
let else_state_id = get_next_state_id () in
918926
let next_state_id = get_next_state_id () in
919927
print_endline (Printf.sprintf "if-then-else cur:%d,then:%d,else:%d,next:%d,back:%d" state_id then_state_id else_state_id next_state_id back_state_id);
920-
loop bb_then then_state_id next_state_id [] while_loop;
921-
loop bb_else else_state_id next_state_id [] while_loop;
922-
loop bb_next next_state_id back_state_id [] while_loop;
928+
loop bb_then then_state_id next_state_id [] while_loop exc_state_id_getter;
929+
loop bb_else else_state_id next_state_id [] while_loop exc_state_id_getter;
930+
loop bb_next next_state_id back_state_id [] while_loop exc_state_id_getter;
923931
let eif = mk (TIf (econd, set_state then_state_id, Some (set_state else_state_id))) com.basic.tint p in
924932
add_state (current_el @ el @ [eif])
925933

@@ -931,20 +939,20 @@ and block_to_texpr_coroutine ctx bb vcontinuation vresult verror p =
931939
(* TODO: variable capture and other fancy things O_o *)
932940
let case_state_id = get_next_state_id () in
933941
print_endline (Printf.sprintf " case %d" case_state_id);
934-
loop bb case_state_id next_state_id [] while_loop;
942+
loop bb case_state_id next_state_id [] while_loop exc_state_id_getter;
935943
patterns, set_state case_state_id
936944
) cases in
937945
let default_state_id = match bb_default with
938946
| Some bb ->
939947
let default_state_id = get_next_state_id () in
940-
loop bb default_state_id next_state_id [] while_loop;
948+
loop bb default_state_id next_state_id [] while_loop exc_state_id_getter;
941949
default_state_id
942950
| None ->
943951
next_state_id
944952
in
945953
print_endline (Printf.sprintf " default %d" default_state_id);
946954
let eswitch = mk (TSwitch (esubj,ecases,Some (set_state default_state_id))) com.basic.tvoid p in
947-
loop bb_next next_state_id back_state_id [] while_loop;
955+
loop bb_next next_state_id back_state_id [] while_loop exc_state_id_getter;
948956
add_state (current_el @ el @ [eswitch])
949957

950958
| SEWhile (bb_body, bb_next, p) ->
@@ -953,23 +961,24 @@ and block_to_texpr_coroutine ctx bb vcontinuation vresult verror p =
953961
print_endline (Printf.sprintf "while cur:%d,body:%d,next:%d,back:%d" state_id body_state_id next_state_id back_state_id);
954962
let new_while_loop = Some (body_state_id,next_state_id) in
955963
(* TODO: next is empty? *)
956-
loop bb_body body_state_id body_state_id [] new_while_loop;
957-
loop bb_next next_state_id back_state_id [] while_loop;
964+
loop bb_body body_state_id body_state_id [] new_while_loop exc_state_id_getter;
965+
loop bb_next next_state_id back_state_id [] while_loop exc_state_id_getter;
958966
add_state (current_el @ el @ [set_state body_state_id]);
959967

960968
| SETry (bb_try,_,catches,bb_next,p) ->
961969
let try_state_id = get_next_state_id () in
962970
let new_exc_state_id = get_next_state_id () in
963971
let next_state_id = get_next_state_id () in
964972
print_endline (Printf.sprintf "try cur:%d,try:%d,catch:%d,next:%d,back:%d" state_id try_state_id new_exc_state_id next_state_id back_state_id);
965-
loop bb_try try_state_id next_state_id [set_excstate new_exc_state_id] while_loop;
973+
loop bb_try try_state_id next_state_id [set_excstate new_exc_state_id] while_loop (fun () -> new_exc_state_id); (* TODO: add test for nested try/catch *)
974+
let esetexcstate = set_excstate (exc_state_id_getter ()) in
966975
let catch_case =
967976
let erethrow = mk (TThrow eerror) t_dynamic null_pos in
968977
let eif =
969978
List.fold_left (fun enext (vcatch,bb_catch) ->
970979
let catch_state_id = get_next_state_id () in
971980
let ecatchvar = mk (TVar (vcatch, Some eerror)) com.basic.tvoid null_pos in
972-
loop bb_catch catch_state_id next_state_id [ecatchvar] while_loop;
981+
loop bb_catch catch_state_id next_state_id [esetexcstate; ecatchvar] while_loop exc_state_id_getter;
973982

974983
(* TODO: exceptions filter... *)
975984
match follow vcatch.v_type with
@@ -983,21 +992,12 @@ and block_to_texpr_coroutine ctx bb vcontinuation vresult verror p =
983992
(new_exc_state_id, eif)
984993
in
985994
exc_states := catch_case :: !exc_states;
986-
loop bb_next next_state_id back_state_id [(* TODO: set back to previous exc_state_id, which is not know atm *)] while_loop;
995+
loop bb_next next_state_id back_state_id [esetexcstate (* TODO: test propagation after try/catch *)] while_loop exc_state_id_getter;
987996
add_state (current_el @ el @ [set_state try_state_id])
988997
in
989-
loop bb (get_next_state_id ()) (-1) [] None;
990-
991-
let rethrow_state_id = get_next_state_id () in
992-
993-
(* prepend setting exceptionState to the rethrow one *)
994-
let exc_states =
995-
List.map (fun (id, e) ->
996-
id, mk (TBlock [set_excstate rethrow_state_id; e]) com.basic.tvoid null_pos
997-
) !exc_states
998-
in
998+
loop bb (get_next_state_id ()) (-1) [] None get_rethrow_state_id;
999999

1000-
let states = !states @ exc_states in
1000+
let states = !states @ !exc_states in
10011001

10021002
(* TODO: this (and the coroutine transform in general) should probably be run before captured vars handling *)
10031003
(* very ugly, but seems to work: extract locals that are used across states *)
@@ -1062,6 +1062,7 @@ and block_to_texpr_coroutine ctx bb vcontinuation vresult verror p =
10621062
- if there's only one state (no suspensions) - don't wrap into while/switch, don't introduce state var
10631063
*)
10641064

1065+
let rethrow_state_id = get_rethrow_state_id () in
10651066
let rethrow_state = (rethrow_state_id, mk (TThrow eerror) com.basic.tvoid null_pos) in
10661067
let states = states @ [rethrow_state] in
10671068

0 commit comments

Comments
 (0)