@@ -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 ;
0 commit comments