Skip to content

Commit 5a2090d

Browse files
committed
some insane try/catch mess and more TODOs
1 parent 9491921 commit 5a2090d

File tree

2 files changed

+72
-12
lines changed

2 files changed

+72
-12
lines changed

src/optimization/analyzerTexprTransformer.ml

Lines changed: 36 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -813,22 +813,35 @@ and block_to_texpr_coroutine ctx bb vcontinuation vresult verror p =
813813
mk (TCall (ecreatecoroutine, [enull; enull])) com.basic.tvoid call.pos
814814
in
815815

816+
(* TODO: stolen from exceptions.ml. we should really figure out the filter ordering here *)
817+
let std_is e t =
818+
let std_cls =
819+
(* TODO: load it? *)
820+
match (try List.find (fun t -> t_path t = ([],"Std")) com.types with Not_found -> die "" __LOC__) with
821+
| TClassDecl cls -> cls
822+
| _ -> die "" __LOC__
823+
in
824+
let isOfType_field =
825+
try PMap.find "isOfType" std_cls.cl_statics
826+
with Not_found -> die "" __LOC__
827+
in
828+
let type_expr = mk (TTypeExpr (module_type_of_type t)) t_dynamic null_pos in
829+
let isOfType_expr = Typecore.make_static_field_access std_cls isOfType_field isOfType_field.cf_type null_pos in
830+
mk (TCall (isOfType_expr, [e; type_expr])) com.basic.tbool null_pos
831+
in
832+
833+
816834
let states = ref [] in
817835

818836
let exc_states = ref [] in
819837

820838
(* TODO: maybe merge this into block_to_texpr somehow, and only introduce new states when there is a suspension point *)
821839
print_endline "---";
822-
let rec loop ?(exc_state=None) bb state_id back_state_id current_el while_loop =
840+
let rec loop bb state_id back_state_id current_el while_loop =
823841
let p = bb.bb_pos in
824842
(* TODO: only do this in the end, avoid unnecessary List.rev *)
825843
let el = DynArray.to_list bb.bb_el in
826844

827-
let el = match exc_state with
828-
| Some id -> set_excstate id :: el
829-
| None -> el
830-
in
831-
832845
let ereturn = mk (TReturn None) com.basic.tvoid p in
833846

834847
let add_state el =
@@ -949,17 +962,28 @@ and block_to_texpr_coroutine ctx bb vcontinuation vresult verror p =
949962
let new_exc_state_id = get_next_state_id () in
950963
let next_state_id = get_next_state_id () in
951964
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);
952-
loop bb_try try_state_id next_state_id [] while_loop ~exc_state:(Some new_exc_state_id);
965+
loop bb_try try_state_id next_state_id [set_excstate new_exc_state_id] while_loop;
953966
let catch_case =
954967
let erethrow = mk (TThrow eerror) t_dynamic null_pos in
955-
(* let eif = List.fold_left (fun acc (v,bb) ->
956-
failwith "TODO: need to rework loop to return el instead of cases"
957-
) erethrow catches in *)
958-
let eif = erethrow in
968+
let eif =
969+
List.fold_left (fun enext (vcatch,bb_catch) ->
970+
let catch_state_id = get_next_state_id () in
971+
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;
973+
974+
(* TODO: exceptions filter... *)
975+
match follow vcatch.v_type with
976+
| TDynamic _ ->
977+
set_state catch_state_id (* no next *)
978+
| t ->
979+
let etypecheck = std_is (make_local verror null_pos) vcatch.v_type in
980+
mk (TIf (etypecheck, set_state catch_state_id, Some enext)) com.basic.tvoid null_pos
981+
) erethrow catches
982+
in
959983
(new_exc_state_id, eif)
960984
in
961985
exc_states := catch_case :: !exc_states;
962-
loop bb_next next_state_id back_state_id [] while_loop;
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;
963987
add_state (current_el @ el @ [set_state try_state_id])
964988
in
965989
loop bb (get_next_state_id ()) (-1) [] None;

tests/misc/coroutines/src/TestControlFlow.hx

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,9 +88,45 @@ class TestControlFlow extends utest.Test {
8888
async.done();
8989
});
9090
}
91+
92+
function testTryCatch(async:Async) {
93+
mapCalls.start([new E1(), new E2()], tryCatch, (result,error) -> {
94+
Assert.same(["e1", "e2"], result);
95+
async.done();
96+
});
97+
}
98+
99+
function testTryCatchFail(async:Async) {
100+
tryCatch.start(new E3(), (result,error) -> {
101+
Assert.isOfType(error, E3);
102+
async.done();
103+
});
104+
}
105+
106+
@:coroutine function tryCatch(e:haxe.Exception) {
107+
try {
108+
throw e;
109+
} catch (e:E1) {
110+
return "e1";
111+
} catch (e:E2) {
112+
return "e2";
113+
}
114+
return "none";
115+
}
91116
}
92117

93118
@:coroutine
94119
private function mapCalls<TArg,TRet>(args:Array<TArg>, f:Coroutine<TArg->TRet>):Array<TRet> {
95120
return [for (arg in args) f(arg)];
96121
}
122+
123+
private class E1 extends haxe.Exception {
124+
public function new() super("E1");
125+
}
126+
127+
private class E2 extends haxe.Exception {
128+
public function new() super("E1");
129+
}
130+
private class E3 extends haxe.Exception {
131+
public function new() super("E1");
132+
}

0 commit comments

Comments
 (0)