瀏覽代碼

use bb_terminator in the coroutine builder too

Dan Korostelev 4 年之前
父節點
當前提交
71dccd19c5
共有 1 個文件被更改,包括 69 次插入72 次删除
  1. 69 72
      src/optimization/analyzerTexprTransformer.ml

+ 69 - 72
src/optimization/analyzerTexprTransformer.ml

@@ -791,6 +791,7 @@ and block_to_texpr_coroutine ctx bb vcontinuation vresult p =
 		let ereturn = mk (TReturn None) com.basic.tvoid p in
 
 		let mk_case el = [make_int com.basic state_id p], mk (TBlock el) com.basic.tvoid p in
+		let get_cond_branch () = match bb.bb_terminator with TermCondBranch e -> e | _ -> die "" __LOC__ in
 
 		match bb.bb_syntax_edge with
 		| SESuspend (call, bb_next) ->
@@ -816,29 +817,34 @@ and block_to_texpr_coroutine ctx bb vcontinuation vresult p =
 
 		| SENone ->
 			print_endline (Printf.sprintf "none cur:%d,back:%d" state_id back_state_id);
-			(match List.rev el with
-			| { eexpr = TBreak } :: el_rev ->
+			(match bb.bb_terminator with
+			| TermBreak _ -> (* todo use pos *)
 				let _,next_state_id = Option.get while_loop in
 				let esetstate = set_state next_state_id in
-				mk_case (current_el @ (List.rev (esetstate :: el_rev))) :: statecases
-			| { eexpr = TContinue } :: el_rev ->
+				mk_case (current_el @ el @ [esetstate]) :: statecases
+			| TermContinue _ -> (* todo use pos *)
 				let body_state_id,_ = Option.get while_loop in
 				let esetstate = set_state body_state_id in
-				mk_case (current_el @ (List.rev (esetstate :: el_rev))) :: statecases
-			| { eexpr = TReturn ret } :: el_rev ->
+				mk_case (current_el @ el @ [esetstate]) :: statecases
+			| TermReturn _ | TermReturnValue _ -> (* todo use pos *)
 				let esetstate = set_state (-1) in
-				let eresult = match ret with
-					| Some e -> e
-					| None -> make_null t_dynamic p
+				let eresult = match bb.bb_terminator with
+					| TermReturnValue (e,_) -> e
+					| _ -> make_null t_dynamic p
 				in
 				let ecallcontinuation = mk_continuation_call eresult p in
-				mk_case (current_el @ List.rev (ereturn :: ecallcontinuation :: esetstate :: el_rev)) :: statecases
-			| _ when back_state_id = -1 ->
+				mk_case (current_el @ el @ [esetstate; ecallcontinuation; ereturn]) :: statecases
+			| TermNone when back_state_id = -1 ->
 				let esetstate = set_state (-1) in
 				let ecallcontinuation = mk_continuation_call (make_null t_dynamic p) p in
 				mk_case (current_el @ el @ [esetstate; ecallcontinuation; ereturn]) :: statecases
-			| _ ->
-				mk_case (current_el @ el @ [set_state back_state_id]) :: statecases)
+			| TermNone ->
+				mk_case (current_el @ el @ [set_state back_state_id]) :: statecases
+			| TermThrow (_,p) ->
+				Error.error "throw is currently not supported in coroutines" p
+			| TermCondBranch _ ->
+				die "unexpected TermCondBranch" __LOC__)
+
 		| SEMerge bb_next ->
 			print_endline (Printf.sprintf "merge cur:%d,back:%d" state_id back_state_id);
 			loop bb_next state_id back_state_id statecases (current_el @ el) while_loop
@@ -852,70 +858,61 @@ and block_to_texpr_coroutine ctx bb vcontinuation vresult p =
 			mk_case (current_el @ el @ [set_state sub_state_id]) :: statecases
 
 		| SEIfThen (bb_then,bb_next,p) ->
-			(match List.rev el with
-			| econd :: el_rev ->
-				let then_state_id = get_next_state_id () in
-				let next_state_id = get_next_state_id () in
-				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);
-				let statecases = loop bb_then then_state_id next_state_id statecases [] while_loop in
-				let statecases = loop bb_next next_state_id back_state_id statecases [] while_loop in
-				let eif = mk (TIf (econd, set_state then_state_id, Some (set_state next_state_id))) com.basic.tint p in
-				mk_case (current_el @ (List.rev el_rev) @ [eif]) :: statecases
-			| _ -> die "" __LOC__)
+			let econd = get_cond_branch () in
+			let then_state_id = get_next_state_id () in
+			let next_state_id = get_next_state_id () in
+			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);
+			let statecases = loop bb_then then_state_id next_state_id statecases [] while_loop in
+			let statecases = loop bb_next next_state_id back_state_id statecases [] while_loop in
+			let eif = mk (TIf (econd, set_state then_state_id, Some (set_state next_state_id))) com.basic.tint p in
+			mk_case (current_el @ el @ [eif]) :: statecases
 
 		| SEIfThenElse (bb_then,bb_else,bb_next,t,p) ->
-			(match List.rev el with
-			| econd :: el_rev ->
-				let then_state_id = get_next_state_id () in
-				let else_state_id = get_next_state_id () in
-				let next_state_id = get_next_state_id () in
-				print_endline (Printf.sprintf "if-then cur:%d,then:%d,else:%d,next:%d,back:%d" state_id then_state_id else_state_id next_state_id back_state_id);
-				let statecases = loop bb_then then_state_id next_state_id statecases [] while_loop in
-				let statecases = loop bb_else else_state_id next_state_id statecases [] while_loop in
-				let statecases = loop bb_next next_state_id back_state_id statecases [] while_loop in
-				let eif = mk (TIf (econd, set_state then_state_id, Some (set_state else_state_id))) com.basic.tint p in
-				mk_case (current_el @ (List.rev el_rev) @ [eif]) :: statecases
-			| _ -> die "" __LOC__)
+			let econd = get_cond_branch () in
+			let then_state_id = get_next_state_id () in
+			let else_state_id = get_next_state_id () in
+			let next_state_id = get_next_state_id () in
+			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);
+			let statecases = loop bb_then then_state_id next_state_id statecases [] while_loop in
+			let statecases = loop bb_else else_state_id next_state_id statecases [] while_loop in
+			let statecases = loop bb_next next_state_id back_state_id statecases [] while_loop in
+			let eif = mk (TIf (econd, set_state then_state_id, Some (set_state else_state_id))) com.basic.tint p in
+			mk_case (current_el @ el @ [eif]) :: statecases
 
 		| SESwitch (cases,bb_default,bb_next,p) ->
-			(match List.rev el with
-			| esubj :: el ->
-				let next_state_id = get_next_state_id () in
-				print_endline (Printf.sprintf "switch cur:%d,next:%d,back:%d" state_id next_state_id back_state_id);
-				let statecases = ref statecases in
-				let ecases = List.map (fun (patterns,bb) ->
-					(* TODO: variable capture and other fancy things O_o *)
-					let case_state_id = get_next_state_id () in
-					print_endline (Printf.sprintf "  case %d" case_state_id);
-					statecases := loop bb case_state_id next_state_id !statecases [] while_loop;
-					patterns, set_state case_state_id
-				) cases in
-				let default_state_id = match bb_default with
-					| Some bb ->
-						let default_state_id = get_next_state_id () in
-						statecases := loop bb default_state_id next_state_id !statecases [] while_loop;
-						default_state_id
-					| None ->
-						next_state_id
-				in
-				print_endline (Printf.sprintf "  default %d" default_state_id);
-				let eswitch = mk (TSwitch (esubj,ecases,Some (set_state default_state_id))) com.basic.tvoid p in
-				let statecases = loop bb_next next_state_id back_state_id !statecases [] while_loop in
-				mk_case (current_el @ (List.rev el) @ [eswitch]) :: statecases
-			| _ -> die "" __LOC__)
+			let esubj = get_cond_branch () in
+			let next_state_id = get_next_state_id () in
+			print_endline (Printf.sprintf "switch cur:%d,next:%d,back:%d" state_id next_state_id back_state_id);
+			let statecases = ref statecases in
+			let ecases = List.map (fun (patterns,bb) ->
+				(* TODO: variable capture and other fancy things O_o *)
+				let case_state_id = get_next_state_id () in
+				print_endline (Printf.sprintf "  case %d" case_state_id);
+				statecases := loop bb case_state_id next_state_id !statecases [] while_loop;
+				patterns, set_state case_state_id
+			) cases in
+			let default_state_id = match bb_default with
+				| Some bb ->
+					let default_state_id = get_next_state_id () in
+					statecases := loop bb default_state_id next_state_id !statecases [] while_loop;
+					default_state_id
+				| None ->
+					next_state_id
+			in
+			print_endline (Printf.sprintf "  default %d" default_state_id);
+			let eswitch = mk (TSwitch (esubj,ecases,Some (set_state default_state_id))) com.basic.tvoid p in
+			let statecases = loop bb_next next_state_id back_state_id !statecases [] while_loop in
+			mk_case (current_el @ el @ [eswitch]) :: statecases
 
-		| SEWhile (_, bb_body, bb_next) ->
-			(match List.rev el with
-			| { eexpr = TWhile _} :: el_rev ->
-				let body_state_id = get_next_state_id () in
-				let next_state_id = get_next_state_id () in
-				print_endline (Printf.sprintf "while cur:%d,body:%d,next:%d,back:%d" state_id body_state_id next_state_id back_state_id);
-				let new_while_loop = Some (body_state_id,next_state_id) in
-				(* TODO: next is empty? *)
-				let statecases = loop bb_body body_state_id body_state_id statecases [] new_while_loop in
-				let statecases = loop bb_next next_state_id back_state_id statecases [] while_loop in
-				mk_case (current_el @ (List.rev (set_state body_state_id :: el_rev))) :: statecases
-			| _ -> die "" __LOC__)
+		| SEWhile (_, bb_body, bb_next, p) ->
+			let body_state_id = get_next_state_id () in
+			let next_state_id = get_next_state_id () in
+			print_endline (Printf.sprintf "while cur:%d,body:%d,next:%d,back:%d" state_id body_state_id next_state_id back_state_id);
+			let new_while_loop = Some (body_state_id,next_state_id) in
+			(* TODO: next is empty? *)
+			let statecases = loop bb_body body_state_id body_state_id statecases [] new_while_loop in
+			let statecases = loop bb_next next_state_id back_state_id statecases [] while_loop in
+			mk_case (current_el @ el @ [set_state body_state_id]) :: statecases
 
 		| SETry (_,_,_,_,p) ->
 			Error.error "try/catch is currently not supported in coroutines" p