@@ -103,7 +103,7 @@ let expr_deps blocks vars deps defs x e =
103103 | Closure (l , cont ) ->
104104 List. iter l ~f: (fun x -> add_param_def vars defs x);
105105 cont_deps blocks vars deps defs cont
106- | Block (_ , a , _ ) -> Array. iter a ~f: (fun y -> add_dep deps x y)
106+ | Block (_ , a , _ , _ ) -> Array. iter a ~f: (fun y -> add_dep deps x y)
107107 | Field (y , _ ) -> add_dep deps x y
108108
109109let program_deps { blocks; _ } =
@@ -152,7 +152,7 @@ let propagate1 deps defs st x =
152152 var_set_lift
153153 (fun z ->
154154 match defs.(Var. idx z) with
155- | Expr (Block (_ , a , _ )) when n < Array. length a ->
155+ | Expr (Block (_ , a , _ , _ )) when n < Array. length a ->
156156 let t = a.(n) in
157157 add_dep deps x t;
158158 Var.Tbl. get st t
@@ -186,15 +186,17 @@ type mutability_state =
186186 ; possibly_mutable : Code.Var.ISet .t
187187 }
188188
189- let rec block_escape st x =
189+ let rec block_escape st ?( immutable = false ) x =
190190 Var.Set. iter
191191 (fun y ->
192192 if not (Code.Var.ISet. mem st.may_escape y)
193193 then (
194194 Code.Var.ISet. add st.may_escape y;
195- Code.Var.ISet. add st.possibly_mutable y;
195+ if not immutable then Code.Var.ISet. add st.possibly_mutable y;
196+
196197 match st.defs.(Var. idx y) with
197- | Expr (Block (_ , l , _ )) -> Array. iter l ~f: (fun z -> block_escape st z)
198+ | Expr (Block (_ , l , _ , immutable )) ->
199+ Array. iter l ~f: (fun z -> block_escape st ~immutable z)
198200 | _ -> () ))
199201 (Var.Tbl. get st.known_origins x)
200202
@@ -226,15 +228,18 @@ let expr_escape st _x e =
226228 | Pv v , `Shallow_const -> (
227229 match st.defs.(Var. idx v) with
228230 | Expr (Constant (Tuple _ )) -> ()
229- | Expr (Block (_ , a , _ )) -> Array. iter a ~f: (fun x -> block_escape st x)
231+ | Expr (Block (_ , a , _ , true )) ->
232+ Array. iter a ~f: (fun x -> block_escape st ~immutable: true x)
233+ | Expr (Block (_ , a , _ , false )) ->
234+ Array. iter a ~f: (fun x -> block_escape st x)
230235 | _ -> block_escape st v)
231236 | Pv v , `Object_literal -> (
232237 match st.defs.(Var. idx v) with
233238 | Expr (Constant (Tuple _ )) -> ()
234- | Expr (Block (_ , a , _ )) ->
239+ | Expr (Block (_ , a , _ , _ )) ->
235240 Array. iter a ~f: (fun x ->
236241 match st.defs.(Var. idx x) with
237- | Expr (Block (_ , [| _k; v |], _ )) -> block_escape st v
242+ | Expr (Block (_ , [| _k; v |], _ , _ )) -> block_escape st v
238243 | Expr (Constant _ ) -> ()
239244 | _ -> block_escape st x)
240245 | _ -> block_escape st v)
@@ -282,7 +287,7 @@ let propagate2 ?(skip_param = false) defs known_origins possibly_mutable st x =
282287 || Var.Set. exists
283288 (fun z ->
284289 match defs.(Var. idx z) with
285- | Expr (Block (_ , a , _ )) ->
290+ | Expr (Block (_ , a , _ , _ )) ->
286291 n > = Array. length a
287292 || Var.ISet. mem possibly_mutable z
288293 || Var.Tbl. get st a.(n)
@@ -382,7 +387,7 @@ let direct_approx (info : Info.t) x =
382387 then None
383388 else
384389 match info.info_defs.(Var. idx z) with
385- | Expr (Block (_ , a , _ )) when n < Array. length a -> Some a.(n)
390+ | Expr (Block (_ , a , _ , _ )) when n < Array. length a -> Some a.(n)
386391 | _ -> None )
387392 None
388393 (fun u v ->
@@ -392,6 +397,29 @@ let direct_approx (info : Info.t) x =
392397 y
393398 | _ -> None
394399
400+ let rec the_shape_of info x =
401+ get_approx
402+ info
403+ (fun x ->
404+ if Var.ISet. mem info.info_possibly_mutable x
405+ then Shape. Bot " possibly_mutable"
406+ else
407+ match info.info_defs.(Var. idx x) with
408+ | Expr (Block (_ , a , _ , true )) ->
409+ Shape. Block (List. map ~f: (the_shape_of info) (Array. to_list a))
410+ | Expr (Closure (l , _ )) ->
411+ Shape. Function { arity = List. length l; pure = false ; res = Bot " unk" }
412+ | Expr (Special (Alias_prim name )) -> (
413+ try
414+ let arity = Primitive. arity name in
415+ let pure = Primitive. is_pure name in
416+ Shape. Function { arity; pure; res = Bot " unk" }
417+ with _ -> Bot " other" )
418+ | _ -> Shape. Bot " other" )
419+ (Bot " init" )
420+ (fun _u _v -> Shape. Bot " merge" )
421+ x
422+
395423let build_subst (info : Info.t ) vars =
396424 let nv = Var. count () in
397425 let subst = Array. init nv ~f: (fun i -> Var. of_idx i) in
0 commit comments