Explorar o código

better perf of exceptions filter
if catch var is never used (#9848)

Aleksandr Kuzmenko %!s(int64=5) %!d(string=hai) anos
pai
achega
543670baf9
Modificáronse 1 ficheiros con 56 adicións e 31 borrados
  1. 56 31
      src/filters/exceptions.ml

+ 56 - 31
src/filters/exceptions.ml

@@ -186,6 +186,54 @@ let set_needs_exception_stack v =
 	if not (Meta.has Meta.NeedsExceptionStack v.v_meta) then
 		v.v_meta <- (Meta.NeedsExceptionStack,[],null_pos) :: v.v_meta
 
+class catch ctx catch_local catch_pos =
+	object (self)
+		(* val mutable hx_exception_var = None *)
+		val mutable hx_exception_local = None
+		(* val mutable unwrapped_var = None *)
+		val mutable unwrapped_local = None
+
+		method get_haxe_exception =
+			match hx_exception_local with
+			| None ->
+				let v = gen_local ctx.typer ctx.haxe_exception_type null_pos in
+				let e = mk (TLocal v) v.v_type null_pos in
+				(* hx_exception_var <- Some v; *)
+				hx_exception_local <- Some e;
+				e
+			| Some e -> e
+
+		method unwrap =
+			match unwrapped_local with
+			| None ->
+				let v = gen_local ctx.typer t_dynamic null_pos in
+				let e = mk (TLocal v) v.v_type null_pos in
+				(* unwrapped_var <- Some v; *)
+				unwrapped_local <- Some e;
+				e
+			| Some e -> e
+
+		method declare_haxe_exception =
+			match hx_exception_local with
+			| Some { eexpr = TLocal v } ->
+				let caught = haxe_exception_static_call ctx "caught" [catch_local] null_pos in
+				mk (TVar (v, Some caught)) ctx.basic.tvoid null_pos
+			| None ->
+				mk (TBlock[]) ctx.basic.tvoid null_pos;
+			| _ ->
+				die ~p:catch_pos "Unexpected expression generated for catch variable" __LOC__
+
+		method declare_unwrap =
+			match unwrapped_local with
+			| Some { eexpr = TLocal v } ->
+				let unwrap = haxe_exception_instance_call ctx self#get_haxe_exception "unwrap" [] null_pos in
+				mk (TVar (v, Some unwrap)) ctx.basic.tvoid null_pos
+			| None ->
+				mk (TBlock[]) ctx.basic.tvoid null_pos;
+			| _ ->
+				die ~p:catch_pos "Unexpected expression generated for catch unwrap variable" __LOC__
+	end
+
 (**
 	Transform user-written `catches` to a set of catches, which would not require
 	special handling in the target generator.
@@ -229,21 +277,7 @@ let catch_native ctx catches t p =
 			let catch_var = gen_local ctx.typer ctx.wildcard_catch_type null_pos in
 			let catch_local = mk (TLocal catch_var) catch_var.v_type null_pos in
 			let body =
-				let haxe_exception_var = gen_local ctx.typer ctx.haxe_exception_type null_pos in
-				let haxe_exception_local = mk (TLocal haxe_exception_var) haxe_exception_var.v_type null_pos in
-				let unwrapped_var = gen_local ctx.typer t_dynamic null_pos in
-				let unwrapped_local = mk (TLocal unwrapped_var) unwrapped_var.v_type null_pos in
-				let needs_haxe_exception = ref false
-				and needs_unwrap = ref false in
-				let get_haxe_exception() =
-					needs_haxe_exception := true;
-					haxe_exception_local
-				and unwrap() =
-					needs_haxe_exception := true;
-					needs_unwrap := true;
-					unwrapped_local;
-				in
-				let catch_var_used = ref false in
+				let catch = new catch ctx catch_local p in
 				let rec transform = function
 					| (v, body) :: rest ->
 						let current_t = Abstract.follow_with_abstracts v.v_type in
@@ -255,14 +289,14 @@ let catch_native ctx catches t p =
 								if fast_eq ctx.haxe_exception_type current_t then
 									mk (TConst (TBool true)) ctx.basic.tbool v.v_pos
 								else begin
-									std_is ctx (get_haxe_exception()) v.v_type v.v_pos
+									std_is ctx catch#get_haxe_exception v.v_type v.v_pos
 								end
 							in
 							let body =
 								if var_used then
 									mk (TBlock [
 										(* var v:ExceptionType = cast haxe_exception_local; *)
-										mk (TVar (v, Some (mk_cast (get_haxe_exception()) v.v_type null_pos))) ctx.basic.tvoid null_pos;
+										mk (TVar (v, Some (mk_cast catch#get_haxe_exception v.v_type null_pos))) ctx.basic.tvoid null_pos;
 										body
 									]) body.etype body.epos
 								else
@@ -279,7 +313,7 @@ let catch_native ctx catches t p =
 									mk (TBlock [
 										(* var v:Dynamic = haxe_exception_local.unwrap(); *)
 										if var_used then
-											mk (TVar (v, Some (unwrap()))) ctx.basic.tvoid null_pos
+											mk (TVar (v, Some catch#unwrap)) ctx.basic.tvoid null_pos
 										else
 											mk (TBlock[]) ctx.basic.tvoid null_pos;
 										body
@@ -309,15 +343,14 @@ let catch_native ctx catches t p =
 						else begin
 							set_needs_exception_stack catch_var;
 							let condition =
-								catch_var_used := true;
 								(* Std.isOfType(haxe_exception_local.unwrap(), ExceptionType) *)
-								std_is ctx (unwrap()) v.v_type v.v_pos
+								std_is ctx catch#unwrap v.v_type v.v_pos
 							in
 							let body =
 								mk (TBlock [
 									(* var v:ExceptionType = cast haxe_exception_local.unwrap() *)
 									if var_used then
-										mk (TVar (v, Some (mk_cast (unwrap()) v.v_type null_pos))) ctx.basic.tvoid null_pos
+										mk (TVar (v, Some (mk_cast catch#unwrap v.v_type null_pos))) ctx.basic.tvoid null_pos
 									else
 										mk (TBlock[]) ctx.basic.tvoid null_pos;
 									body
@@ -338,17 +371,9 @@ let catch_native ctx catches t p =
 				(* haxe.Exception.caught(catch_var) *)
 				let exprs = [
 					(* var haxe_exception_local = haxe.Exception.caught(catch_var); *)
-					if !needs_haxe_exception then
-						let caught = haxe_exception_static_call ctx "caught" [catch_local] null_pos in
-						mk (TVar (haxe_exception_var, Some caught)) ctx.basic.tvoid null_pos
-					else
-						mk (TBlock[]) ctx.basic.tvoid null_pos;
+					catch#declare_haxe_exception;
 					(* var unwrapped_local = haxe_exception_local.unwrap(); *)
-					if !needs_unwrap then
-						let unwrap = haxe_exception_instance_call ctx haxe_exception_local "unwrap" [] null_pos in
-						mk (TVar (unwrapped_var, Some unwrap)) ctx.basic.tvoid null_pos
-					else
-						mk (TBlock[]) ctx.basic.tvoid null_pos;
+					catch#declare_unwrap;
 					transformed_catches
 				] in
 				mk (TBlock exprs) t p