Dan Korostelev 4 лет назад
Родитель
Сommit
abcd0d5a37

+ 4 - 5
src/optimization/analyzer.ml

@@ -941,7 +941,7 @@ module Run = struct
 		timer();
 		r
 
-	let create_analyzer_context com config e is_coroutine =
+	let create_analyzer_context com config e =
 		let g = Graph.create e.etype e.epos in
 		let ctx = {
 			com = com;
@@ -951,7 +951,6 @@ module Run = struct
 			   avoid problems with the debugger, see https://github.com/HaxeFoundation/hxcpp/issues/365 *)
 			temp_var_name = (match com.platform with Cpp -> "_hx_tmp" | _ -> "tmp");
 			entry = g.g_unreachable;
-			coroutine = if is_coroutine then Some (alloc_var VGenerated "_hx_result" t_dynamic e.epos) else None;
 			has_unbound = false;
 			loop_counter = 0;
 			loop_stack = [];
@@ -1063,7 +1062,7 @@ module Run = struct
 	let run_on_field ctx config c cf = match cf.cf_expr with
 		| Some e when not (is_ignored cf.cf_meta) && not (Typecore.is_removable_field ctx cf) ->
 			let config = update_config_from_meta ctx.Typecore.com config cf.cf_meta in
-			let actx = create_analyzer_context ctx.Typecore.com config e (Meta.has Meta.Coroutine cf.cf_meta) in
+			let actx = create_analyzer_context ctx.Typecore.com config e in
 			let debug() =
 				print_endline (Printf.sprintf "While analyzing %s.%s" (s_type_path c.cl_path) cf.cf_name);
 				List.iter (fun (s,e) ->
@@ -1117,7 +1116,7 @@ module Run = struct
 			| Some e ->
 				let tf = { tf_args = []; tf_type = e.etype; tf_expr = e; } in
 				let e = mk (TFunction tf) (tfun [] e.etype) e.epos in
-				let actx = create_analyzer_context ctx.Typecore.com {config with optimize = false} e false in
+				let actx = create_analyzer_context ctx.Typecore.com {config with optimize = false} e in
 				let e = run_on_expr actx e in
 				let e = match e.eexpr with
 					| TFunction tf -> tf.tf_expr
@@ -1149,6 +1148,6 @@ Typecore.analyzer_run_on_expr_ref := (fun com e ->
 	(* We always want to optimize because const propagation might be required to obtain
 	   a constant expression for inline field initializations (see issue #4977). *)
 	let config = {config with AnalyzerConfig.optimize = true} in
-	let actx = Run.create_analyzer_context com config e false in
+	let actx = Run.create_analyzer_context com config e in
 	Run.run_on_expr actx e
 )

+ 9 - 6
src/optimization/analyzerTexprTransformer.ml

@@ -44,7 +44,11 @@ let rec func ctx bb tf t p =
 	in
 	let bb_root = create_node (BKFunctionBegin tf) tf.tf_expr.etype tf.tf_expr.epos in
 	let bb_exit = create_node BKFunctionEnd tf.tf_expr.etype tf.tf_expr.epos in
-	add_function g tf t p bb_root;
+	let coroutine = match follow t with
+		| TAbstract ({a_path=[],"Coroutine"}, _) -> Some (alloc_var VGenerated "_hx_result" t_dynamic p)
+		| _ -> None
+	in
+	add_function g tf t p bb_root coroutine;
 	add_cfg_edge bb bb_root CFGFunction;
 	let bb_breaks = ref [] in
 	let bb_continue = ref None in
@@ -324,7 +328,7 @@ let rec func ctx bb tf t p =
 					| TAbstract ({ a_path = [], "Coroutine"}, _) -> true
 					| _ -> false
 				in
-				(match ctx.coroutine with
+				(match coroutine with
 					| Some vresult when is_coroutine efun ->
 						let bb_next = create_node BKNormal e1.etype e1.epos in
 						add_cfg_edge bb bb_next CFGGoto;
@@ -909,9 +913,9 @@ and block_to_texpr_coroutine ctx bb vcontinuation vresult p =
 	]) com.basic.tvoid p
 
 and func ctx i =
-	let bb,t,p,tf = Hashtbl.find ctx.graph.g_functions i in
+	let bb,t,p,tf,coroutine = Hashtbl.find ctx.graph.g_functions i in
 	let e,tf_args,tf_type =
-		match ctx.coroutine with
+		match coroutine with
 		| Some vresult ->
 			let vcontinuation = alloc_var VGenerated "_hx_continuation" (tfun [t_dynamic] ctx.com.basic.tvoid) p in
 			declare_var ctx.graph vcontinuation bb;
@@ -956,8 +960,7 @@ and func ctx i =
 					{e with eexpr = TBinop(OpAssign,e1,{e4 with eexpr = TBinop(op,e2,e3)})}
 			end
 		| TCall({eexpr = TConst (TString "fun")},[{eexpr = TConst (TInt i32)}]) ->
-			(* TODO: coroutine-ness of a function must be per-function, not a context field *)
-			func { ctx with coroutine = None } (Int32.to_int i32)
+			func ctx (Int32.to_int i32)
 		| TCall({eexpr = TIdent s},_) when is_really_unbound s ->
 			e
 		| _ ->

+ 4 - 5
src/optimization/analyzerTypes.ml

@@ -246,7 +246,7 @@ end
 module Graph = struct
 	open BasicBlock
 
-	type tfunc_info = BasicBlock.t * Type.t * pos * tfunc
+	type tfunc_info = BasicBlock.t * Type.t * pos * tfunc * tvar option
 	type texpr_lookup = BasicBlock.t * texpr_lookup_target
 	type var_write = BasicBlock.t list
 	type 'a itbl = (int,'a) Hashtbl.t
@@ -332,8 +332,8 @@ module Graph = struct
 
 	(* nodes *)
 
-	let add_function g tf t p bb =
-		Hashtbl.add g.g_functions bb.bb_id (bb,t,p,tf)
+	let add_function g tf t p bb coroutine =
+		Hashtbl.add g.g_functions bb.bb_id (bb,t,p,tf,coroutine)
 
 	let alloc_id =
 		let r = ref 1 in
@@ -589,7 +589,7 @@ module Graph = struct
 					()
 			end
 		in
-		Hashtbl.iter (fun _ (bb,_,_,_) -> loop [0] bb) g.g_functions
+		Hashtbl.iter (fun _ (bb,_,_,_,_) -> loop [0] bb) g.g_functions
 end
 
 type analyzer_context = {
@@ -597,7 +597,6 @@ type analyzer_context = {
 	config : AnalyzerConfig.t;
 	graph : Graph.t;
 	temp_var_name : string;
-	coroutine : tvar option; (* if we're in a coroutine, this field will contain a tvar allocated for reentrancy result *)
 	mutable entry : BasicBlock.t;
 	mutable has_unbound : bool;
 	mutable loop_counter : int;