浏览代码

Make abstract cast filter thread-safe (#12125)

* make inliner thread-safe

* put Task.run around the entire callback instead of individual parallelism calls (#12121)

* deal with isOfType

* make exceptions filter thread-safe

* The Parallel Reunion

* yes we do

* it kinda works

* group pararllel filters together and clean up a bit
Simon Krajewski 5 月之前
父节点
当前提交
420f9aa16a

+ 13 - 15
src/context/abstractCast.ml

@@ -200,11 +200,11 @@ let find_array_write_access ctx a tl e1 e2 p =
 		let s_type = s_type (print_context()) in
 		let s_type = s_type (print_context()) in
 		raise_typing_error (Printf.sprintf "No @:arrayAccess function for %s accepts arguments of %s and %s" (s_type (TAbstract(a,tl))) (s_type e1.etype) (s_type e2.etype)) p
 		raise_typing_error (Printf.sprintf "No @:arrayAccess function for %s accepts arguments of %s and %s" (s_type (TAbstract(a,tl))) (s_type e1.etype) (s_type e2.etype)) p
 
 
-let find_multitype_specialization' com a pl p =
+let find_multitype_specialization' platform a pl p =
 	let uctx = default_unification_context () in
 	let uctx = default_unification_context () in
 	let m = mk_mono() in
 	let m = mk_mono() in
 	let tl,definitive_types = Abstract.find_multitype_params a pl in
 	let tl,definitive_types = Abstract.find_multitype_params a pl in
-	if com.platform = Globals.Js && a.a_path = (["haxe";"ds"],"Map") then begin match tl with
+	if platform = Globals.Js && a.a_path = (["haxe";"ds"],"Map") then begin match tl with
 		| t1 :: _ ->
 		| t1 :: _ ->
 			let stack = ref [] in
 			let stack = ref [] in
 			let rec loop t =
 			let rec loop t =
@@ -248,7 +248,7 @@ let find_multitype_specialization com a pl p =
 	let cf,m,_ = find_multitype_specialization' com a pl p in
 	let cf,m,_ = find_multitype_specialization' com a pl p in
 	(cf,m)
 	(cf,m)
 
 
-let handle_abstract_casts ctx e =
+let handle_abstract_casts (scom : SafeCom.t) e =
 	let rec loop e = match e.eexpr with
 	let rec loop e = match e.eexpr with
 		| TNew({cl_kind = KAbstractImpl a} as c,pl,el) ->
 		| TNew({cl_kind = KAbstractImpl a} as c,pl,el) ->
 			if not (Meta.has Meta.MultiType a.a_meta) then begin
 			if not (Meta.has Meta.MultiType a.a_meta) then begin
@@ -259,24 +259,22 @@ let handle_abstract_casts ctx e =
 				| _ -> raise_typing_error ("Cannot construct " ^ (s_type (print_context()) (TAbstract(a,pl)))) e.epos
 				| _ -> raise_typing_error ("Cannot construct " ^ (s_type (print_context()) (TAbstract(a,pl)))) e.epos
 			end else begin
 			end else begin
 				(* a TNew of an abstract implementation is only generated if it is a multi type abstract *)
 				(* a TNew of an abstract implementation is only generated if it is a multi type abstract *)
-				let cf,m,pl = find_multitype_specialization' ctx.com a pl e.epos in
-				let e = make_static_call ctx c cf a pl ((mk (TConst TNull) (TAbstract(a,pl)) e.epos) :: el) m e.epos in
+				let cf,m,pl = find_multitype_specialization' scom.platform a pl e.epos in
+				let e = ExceptionFunctions.make_static_call scom c cf ((mk (TConst TNull) (TAbstract(a,pl)) e.epos) :: el)  m e.epos in
 				{e with etype = m}
 				{e with etype = m}
 			end
 			end
 		| TCall({eexpr = TField(_,FStatic({cl_path=[],"Std"},{cf_name = "string"}))},[e1]) when (match follow e1.etype with TAbstract({a_impl = Some _},_) -> true | _ -> false) ->
 		| TCall({eexpr = TField(_,FStatic({cl_path=[],"Std"},{cf_name = "string"}))},[e1]) when (match follow e1.etype with TAbstract({a_impl = Some _},_) -> true | _ -> false) ->
 			begin match follow e1.etype with
 			begin match follow e1.etype with
-				| TAbstract({a_impl = Some c} as a,tl) ->
+				| TAbstract({a_impl = Some c},tl) ->
 					begin try
 					begin try
 						let cf = PMap.find "toString" c.cl_statics in
 						let cf = PMap.find "toString" c.cl_statics in
-						let call() = make_static_call ctx c cf a tl [e1] ctx.t.tstring e.epos in
-						if not ctx.allow_transform then
-							{ e1 with etype = ctx.t.tstring; epos = e.epos }
-						else if not (is_nullable e1.etype) then
+						let call() = ExceptionFunctions.make_static_call scom c cf [e1] scom.basic.tstring e.epos in
+						if not (is_nullable e1.etype) then
 							call()
 							call()
 						else begin
 						else begin
 							let p = e.epos in
 							let p = e.epos in
-							let chk_null = mk (TBinop (Ast.OpEq, e1, mk (TConst TNull) e1.etype p)) ctx.com.basic.tbool p in
-							mk (TIf (chk_null, mk (TConst (TString "null")) ctx.com.basic.tstring p, Some (call()))) ctx.com.basic.tstring p
+							let chk_null = mk (TBinop (Ast.OpEq, e1, mk (TConst TNull) e1.etype p)) scom.basic.tbool p in
+							mk (TIf (chk_null, mk (TConst (TString "null")) scom.basic.tstring p, Some (call()))) scom.basic.tstring p
 						end
 						end
 					with Not_found ->
 					with Not_found ->
 						e
 						e
@@ -344,14 +342,14 @@ let handle_abstract_casts ctx e =
 								else
 								else
 									el
 									el
 							in
 							in
-							let ecall = make_call ctx ef el tr e.epos in
+							let ecall = ExceptionFunctions.make_call scom ef el tr e.epos in
 							maybe_cast ecall e.etype e.epos
 							maybe_cast ecall e.etype e.epos
 						with Not_found ->
 						with Not_found ->
 							(* quick_field raises Not_found if m is an abstract, we have to replicate the 'using' call here *)
 							(* quick_field raises Not_found if m is an abstract, we have to replicate the 'using' call here *)
 							match follow m with
 							match follow m with
-							| TAbstract({a_impl = Some c} as a,pl) ->
+							| TAbstract({a_impl = Some c},pl) ->
 								let cf = PMap.find fname c.cl_statics in
 								let cf = PMap.find fname c.cl_statics in
-								make_static_call ctx c cf a pl (e2 :: el) e.etype e.epos
+								ExceptionFunctions.make_static_call scom c cf  (e2 :: el) e.etype e.epos
 							| _ -> raise Not_found
 							| _ -> raise Not_found
 						end
 						end
 					| _ ->
 					| _ ->

+ 1 - 1
src/context/safeCom.ml

@@ -149,4 +149,4 @@ let run_expression_filters_safe scom detail_times filters t =
 	| TAbstractDecl _ -> ()
 	| TAbstractDecl _ -> ()
 
 
 let needs_inline scom c cf =
 let needs_inline scom c cf =
-	cf.cf_kind = Method MethInline && (scom.doinline || Typecore.is_forced_inline c cf)
+	cf.cf_kind = Method MethInline && (scom.doinline || Typecore.is_forced_inline c cf)

+ 21 - 1
src/filters/exception/exceptionFunctions.ml

@@ -24,4 +24,24 @@ let is_haxe_exception ?(check_parent=true) (t:Type.t) =
 let is_dynamic t =
 let is_dynamic t =
 	match Abstract.follow_with_abstracts t with
 	match Abstract.follow_with_abstracts t with
 	| TAbstract({ a_path = [],"Dynamic" }, _) -> true
 	| TAbstract({ a_path = [],"Dynamic" }, _) -> true
-	| t -> t == t_dynamic
+	| t -> t == t_dynamic
+
+let make_call scom eon el tret p =
+	let default () =
+		mk (TCall(eon,el)) tret p
+	in
+	match eon.eexpr with
+	| TField(ef,(FStatic(cl,cf) | FInstance(cl,_,cf))) when SafeCom.needs_inline scom (Some cl) cf ->
+		begin match cf.cf_expr with
+		| Some {eexpr = TFunction tf} ->
+			let config = Inline.inline_config (Some cl) cf el tret in
+			Inline.type_inline (Inline.context_of_scom scom) cf tf ef el tret config p false
+		| _ ->
+			default ()
+		end
+	| _ ->
+		default ()
+
+let make_static_call scom c cf el tret p =
+	let ef = Texpr.Builder.make_static_field c cf p in
+	make_call scom ef el tret p

+ 0 - 20
src/filters/exception/exceptions.ml

@@ -21,26 +21,6 @@ type context = {
 	is_of_type : (tclass * tclass_field * Type.t);
 	is_of_type : (tclass * tclass_field * Type.t);
 }
 }
 
 
-let make_call scom eon el tret p =
-	let default () =
-		mk (TCall(eon,el)) tret p
-	in
-	match eon.eexpr with
-	| TField(ef,(FStatic(cl,cf) | FInstance(cl,_,cf))) when SafeCom.needs_inline scom (Some cl) cf ->
-		begin match cf.cf_expr with
-		| Some {eexpr = TFunction tf} ->
-			let config = Inline.inline_config (Some cl) cf el tret in
-			Inline.type_inline (Inline.context_of_scom scom) cf tf ef el tret config p false
-		| _ ->
-			default ()
-		end
-	| _ ->
-		default ()
-
-let make_static_call scom c cf el tret p =
-	let ef = Texpr.Builder.make_static_field c cf p in
-	make_call scom ef el tret p
-
 (**
 (**
 	Generate `haxe.Exception.method_name(args)`
 	Generate `haxe.Exception.method_name(args)`
 *)
 *)

+ 48 - 46
src/filters/filters.ml

@@ -387,8 +387,47 @@ let might_need_cf_unoptimized c cf =
 	| _ ->
 	| _ ->
 		has_class_field_flag cf CfGeneric
 		has_class_field_flag cf CfGeneric
 
 
+let run_safe_filters ectx (scom : SafeCom.t) new_types_array cv_wrapper_impl rename_locals_config pool =
+	let detail_times = Timer.level_from_define scom.defines Define.FilterTimes in
+
+	let filters_before_inlining = [
+		"handle_abstract_casts",AbstractCast.handle_abstract_casts;
+		"local_statics",LocalStatic.run;
+		"fix_return_dynamic_from_void_function",SafeFilters.fix_return_dynamic_from_void_function;
+		"check_local_vars_init",CheckVarInit.check_local_vars_init;
+		"check_abstract_as_value",SafeFilters.check_abstract_as_value;
+		"Tre",if Define.defined scom.defines Define.AnalyzerOptimize then Tre.run else (fun _ e -> e);
+	] in
+
+	let filters_before_analyzer = [
+		"reduce_expression",Optimizer.reduce_expression;
+		"inline_constructors",InlineConstructors.inline_constructors;
+		"Exceptions_filter",(fun _ -> Exceptions.filter ectx);
+		"captured_vars",(fun scom -> CapturedVars.captured_vars scom cv_wrapper_impl);
+	] in
+
+	let filters_after_analyzer = [
+		"sanitize",(fun scom e -> Sanitize.sanitize scom.SafeCom.platform_config e);
+		"add_final_return",(fun _ -> if scom.platform_config.pf_add_final_return then AddFinalReturn.add_final_return else (fun e -> e));
+		"RenameVars",(match scom.platform with
+			| Eval -> (fun _ e -> e)
+			| Jvm -> (fun _ e -> e)
+			| _ -> (fun scom e -> RenameVars.run scom.curclass.cl_path rename_locals_config e)
+		);
+		"mark_switch_break_loops",SafeFilters.mark_switch_break_loops;
+	] in
+
+	Parallel.ParallelArray.iter pool (SafeCom.run_expression_filters_safe scom detail_times filters_before_inlining) new_types_array;
+	Parallel.ParallelArray.iter pool (SafeCom.run_expression_filters_safe scom detail_times filters_before_analyzer) new_types_array;
+
+	(* enter_stage com CAnalyzerStart; *)
+	if scom.platform <> Cross then Analyzer.Run.run_on_types scom pool new_types_array;
+	(* enter_stage com CAnalyzerDone; *)
+	Parallel.ParallelArray.iter pool (SafeCom.run_expression_filters_safe scom detail_times filters_after_analyzer) new_types_array
+
 let run tctx ectx main before_destruction =
 let run tctx ectx main before_destruction =
 	let com = tctx.com in
 	let com = tctx.com in
+	let scom = SafeCom.of_com com in
 	let detail_times = Timer.level_from_define com.defines Define.FilterTimes in
 	let detail_times = Timer.level_from_define com.defines Define.FilterTimes in
 	let new_types = List.filter (fun t ->
 	let new_types = List.filter (fun t ->
 		let cached = is_cached com t in
 		let cached = is_cached com t in
@@ -417,7 +456,7 @@ let run tctx ectx main before_destruction =
 		not cached
 		not cached
 	) com.types in
 	) com.types in
 	let new_types_array = Array.of_list new_types in
 	let new_types_array = Array.of_list new_types in
-	let scom = SafeCom.of_com com in
+
 	(* IMPORTANT:
 	(* IMPORTANT:
 	    There may be types in new_types which have already been post-processed, but then had their m_processed flag unset
 	    There may be types in new_types which have already been post-processed, but then had their m_processed flag unset
 		because they received an additional dependency. This could happen in cases such as @:generic methods in #10635.
 		because they received an additional dependency. This could happen in cases such as @:generic methods in #10635.
@@ -428,63 +467,26 @@ let run tctx ectx main before_destruction =
 		be aware of this.
 		be aware of this.
 	*)
 	*)
 	NullSafety.run com new_types;
 	NullSafety.run com new_types;
-	(* PASS 1: general expression filters *)
-	let filters = [
-		"handle_abstract_casts",AbstractCast.handle_abstract_casts;
-	] in
-	List.iter (run_expression_filters tctx detail_times filters) new_types;
-
 	let cv_wrapper_impl = CapturedVars.get_wrapper_implementation com in
 	let cv_wrapper_impl = CapturedVars.get_wrapper_implementation com in
-	let filters_before_analyzer = [
-		"local_statics",LocalStatic.run;
-		"fix_return_dynamic_from_void_function",SafeFilters.fix_return_dynamic_from_void_function;
-		"check_local_vars_init",CheckVarInit.check_local_vars_init;
-		"check_abstract_as_value",SafeFilters.check_abstract_as_value;
-		"Tre",if defined com Define.AnalyzerOptimize then Tre.run else (fun _ e -> e);
-		"reduce_expression",Optimizer.reduce_expression;
-		"inline_constructors",InlineConstructors.inline_constructors;
-		"Exceptions_filter",(fun _ -> Exceptions.filter ectx);
-		"captured_vars",(fun scom -> CapturedVars.captured_vars scom cv_wrapper_impl);
-	] in
-	let locals = RenameVars.init scom.platform_config com.types in
-	let filters_after_analyzer = [
-		"sanitize",(fun scom e -> Sanitize.sanitize scom.SafeCom.platform_config e);
-		"add_final_return",(fun _ -> if com.config.pf_add_final_return then AddFinalReturn.add_final_return else (fun e -> e));
-		"RenameVars",(match com.platform with
-			| Eval -> (fun _ e -> e)
-			| Jvm -> (fun _ e -> e)
-			| _ -> (fun scom e -> RenameVars.run scom.curclass.cl_path locals e)
-		);
-		"mark_switch_break_loops",SafeFilters.mark_switch_break_loops;
-	] in
-
-	Parallel.run_in_new_pool com.timer_ctx (fun pool ->
+	let rename_locals_config = RenameVars.init scom.SafeCom.platform_config com.types in
+	Parallel.run_in_new_pool scom.timer_ctx (fun pool ->
 		SafeCom.run_with_scom com scom pool (fun () ->
 		SafeCom.run_with_scom com scom pool (fun () ->
-			Parallel.ParallelArray.iter pool (SafeCom.run_expression_filters_safe scom detail_times filters_before_analyzer) new_types_array
-		);
-
-		enter_stage com CAnalyzerStart;
-		if com.platform <> Cross then Analyzer.Run.run_on_types com pool new_types_array;
-		enter_stage com CAnalyzerDone;
-
-		SafeCom.run_with_scom com scom pool (fun () ->
-			Parallel.ParallelArray.iter pool (SafeCom.run_expression_filters_safe scom detail_times filters_after_analyzer) new_types_array
-		);
+			run_safe_filters ectx scom new_types_array cv_wrapper_impl rename_locals_config pool
+		)
 	);
 	);
-
-	with_timer tctx.com.timer_ctx detail_times "callbacks" None (fun () ->
+	with_timer com.timer_ctx detail_times "callbacks" None (fun () ->
 		com.callbacks#run com.error_ext com.callbacks#get_before_save;
 		com.callbacks#run com.error_ext com.callbacks#get_before_save;
 	);
 	);
 	enter_stage com CSaveStart;
 	enter_stage com CSaveStart;
-	with_timer tctx.com.timer_ctx detail_times "save state" None (fun () ->
+	with_timer com.timer_ctx detail_times "save state" None (fun () ->
 		List.iter (fun mt ->
 		List.iter (fun mt ->
 			update_cache_dependencies ~close_monomorphs:true com mt;
 			update_cache_dependencies ~close_monomorphs:true com mt;
 			save_class_state com mt
 			save_class_state com mt
 		) new_types;
 		) new_types;
 	);
 	);
 	enter_stage com CSaveDone;
 	enter_stage com CSaveDone;
-	with_timer tctx.com.timer_ctx detail_times "callbacks" None (fun () ->
+	with_timer com.timer_ctx detail_times "callbacks" None (fun () ->
 		com.callbacks#run com.error_ext com.callbacks#get_after_save;
 		com.callbacks#run com.error_ext com.callbacks#get_after_save;
 	);
 	);
 	before_destruction();
 	before_destruction();
-	destruction tctx scom ectx detail_times main locals
+	destruction tctx scom ectx detail_times main rename_locals_config

+ 2 - 2
src/filters/filtersCommon.ml

@@ -82,6 +82,6 @@ let is_cached com t =
 	let m = (t_infos t).mt_module.m_extra in
 	let m = (t_infos t).mt_module.m_extra in
 	m.m_processed <> 0 && m.m_processed < com.compilation_step
 	m.m_processed <> 0 && m.m_processed < com.compilation_step
 
 
-let apply_filters_once ctx filters t =
+let apply_filters_once ctx scom filters t =
 	let detail_times = (try int_of_string (Common.defined_value_safe ctx.com ~default:"0" Define.FilterTimes) with _ -> 0) in
 	let detail_times = (try int_of_string (Common.defined_value_safe ctx.com ~default:"0" Define.FilterTimes) with _ -> 0) in
-	if not (is_cached ctx.com t) then run_expression_filters ctx detail_times filters t
+	if not (is_cached ctx.com t) then SafeCom.run_expression_filters_safe scom detail_times filters t

+ 3 - 4
src/optimization/analyzer.ml

@@ -1190,12 +1190,11 @@ module Run = struct
 		| TTypeDecl _ -> ()
 		| TTypeDecl _ -> ()
 		| TAbstractDecl _ -> ()
 		| TAbstractDecl _ -> ()
 
 
-	let run_on_types com pool types =
-		let scom = SafeCom.of_com com in
+	let run_on_types scom pool types =
 		let config = get_base_config scom in
 		let config = get_base_config scom in
-		with_timer com.timer_ctx config.detail_times None ["other"] (fun () ->
+		with_timer scom.timer_ctx config.detail_times None ["other"] (fun () ->
 			if config.optimize && config.purity_inference then
 			if config.optimize && config.purity_inference then
-				with_timer com.timer_ctx config.detail_times None ["optimize";"purity-inference"] (fun () -> Purity.infer com);
+				with_timer scom.timer_ctx config.detail_times None ["optimize";"purity-inference"] (fun () -> Purity.infer types);
 			let exc_out = Atomic.make None in
 			let exc_out = Atomic.make None in
 			Parallel.ParallelArray.iter pool (run_on_type scom exc_out pool config) types;
 			Parallel.ParallelArray.iter pool (run_on_type scom exc_out pool config) types;
 			check_exc_out exc_out
 			check_exc_out exc_out

+ 9 - 9
src/optimization/analyzerTexpr.ml

@@ -1159,7 +1159,7 @@ module Purity = struct
 		taint node;
 		taint node;
 		raise Exit
 		raise Exit
 
 
-	let apply_to_field com is_ctor is_static c cf =
+	let apply_to_field is_ctor is_static c cf =
 		let node = get_node c cf in
 		let node = get_node c cf in
 		let check_field c cf =
 		let check_field c cf =
 			let node' = get_node c cf in
 			let node' = get_node c cf in
@@ -1235,24 +1235,24 @@ module Purity = struct
 					with Exit ->
 					with Exit ->
 						()
 						()
 
 
-	let apply_to_class com c =
-		List.iter (apply_to_field com false false c) c.cl_ordered_fields;
-		List.iter (apply_to_field com false true c) c.cl_ordered_statics;
-		(match c.cl_constructor with Some cf -> apply_to_field com true false c cf | None -> ())
+	let apply_to_class c =
+		List.iter (apply_to_field false false c) c.cl_ordered_fields;
+		List.iter (apply_to_field false true c) c.cl_ordered_statics;
+		(match c.cl_constructor with Some cf -> apply_to_field true false c cf | None -> ())
 
 
-	let infer com =
+	let infer types =
 		Hashtbl.clear node_lut;
 		Hashtbl.clear node_lut;
-		List.iter (fun mt -> match mt with
+		Array.iter (fun mt -> match mt with
 			| TClassDecl c ->
 			| TClassDecl c ->
 				begin try
 				begin try
-					apply_to_class com c
+					apply_to_class c
 				with Purity_conflict(impure,p) ->
 				with Purity_conflict(impure,p) ->
 					Error.raise_typing_error_ext (Error.make_error (Custom "Impure field overrides/implements field which was explicitly marked as @:pure") ~sub:[
 					Error.raise_typing_error_ext (Error.make_error (Custom "Impure field overrides/implements field which was explicitly marked as @:pure") ~sub:[
 						Error.make_error ~depth:1 (Custom (Error.compl_msg "Pure field is here")) p
 						Error.make_error ~depth:1 (Custom (Error.compl_msg "Pure field is here")) p
 					] impure.pn_field.cf_pos)
 					] impure.pn_field.cf_pos)
 				end
 				end
 			| _ -> ()
 			| _ -> ()
-		) com.Common.types;
+		) types;
 		Hashtbl.iter (fun _ node ->
 		Hashtbl.iter (fun _ node ->
 			match node.pn_purity with
 			match node.pn_purity with
 			| Pure | MaybePure when not (List.exists (fun (m,_,_) -> m = Meta.Pure) node.pn_field.cf_meta) ->
 			| Pure | MaybePure when not (List.exists (fun (m,_,_) -> m = Meta.Pure) node.pn_field.cf_meta) ->

+ 2 - 2
src/optimization/dce.ml

@@ -286,7 +286,7 @@ and mark_t dce p t =
 				List.iter (loop stack) pl
 				List.iter (loop stack) pl
 			| TAbstract(a,pl) when Meta.has Meta.MultiType a.a_meta ->
 			| TAbstract(a,pl) when Meta.has Meta.MultiType a.a_meta ->
 				begin try
 				begin try
-					loop stack (snd (AbstractCast.find_multitype_specialization dce.com a pl p))
+					loop stack (snd (AbstractCast.find_multitype_specialization dce.com.platform a pl p))
 				with Error.Error _ ->
 				with Error.Error _ ->
 					()
 					()
 				end
 				end
@@ -431,7 +431,7 @@ and mark_directly_used_t dce p t =
 		List.iter (mark_directly_used_t dce p) pl
 		List.iter (mark_directly_used_t dce p) pl
 	| TAbstract(a,pl) when Meta.has Meta.MultiType a.a_meta ->
 	| TAbstract(a,pl) when Meta.has Meta.MultiType a.a_meta ->
 		begin try (* this is copy-pasted from mark_t *)
 		begin try (* this is copy-pasted from mark_t *)
-			mark_directly_used_t dce p (snd (AbstractCast.find_multitype_specialization dce.com a pl p))
+			mark_directly_used_t dce p (snd (AbstractCast.find_multitype_specialization dce.com.platform a pl p))
 		with Error.Error _ ->
 		with Error.Error _ ->
 			()
 			()
 		end
 		end

+ 3 - 9
src/typing/macroContext.ml

@@ -649,15 +649,9 @@ and flush_macro_context mint mctx =
 		let cv_wrapper_impl = CapturedVars.get_wrapper_implementation mctx.com in
 		let cv_wrapper_impl = CapturedVars.get_wrapper_implementation mctx.com in
 		let expr_filters = [
 		let expr_filters = [
 			"handle_abstract_casts",AbstractCast.handle_abstract_casts;
 			"handle_abstract_casts",AbstractCast.handle_abstract_casts;
-			"local_statics",(fun tctx ->
-				let scom = SafeCom.of_typer tctx in
-				LocalStatic.run scom
-			);
+			"local_statics",LocalStatic.run;
 			"Exceptions",(fun _ -> Exceptions.filter ectx);
 			"Exceptions",(fun _ -> Exceptions.filter ectx);
-			"captured_vars",(fun tctx ->
-				let scom = SafeCom.of_typer tctx in
-				CapturedVars.captured_vars scom cv_wrapper_impl
-			);
+			"captured_vars",(fun scom -> CapturedVars.captured_vars scom cv_wrapper_impl);
 		] in
 		] in
 		let type_filters = [
 		let type_filters = [
 			FiltersCommon.remove_generic_base;
 			FiltersCommon.remove_generic_base;
@@ -668,7 +662,7 @@ and flush_macro_context mint mctx =
 			maybe_apply_native_paths
 			maybe_apply_native_paths
 		] in
 		] in
 		let ready = fun t ->
 		let ready = fun t ->
-			FiltersCommon.apply_filters_once mctx expr_filters t;
+			FiltersCommon.apply_filters_once mctx scom expr_filters t;
 			List.iter (fun f -> f t) type_filters
 			List.iter (fun f -> f t) type_filters
 		in
 		in
 		(try Interp.add_types mint types ready
 		(try Interp.add_types mint types ready