@@ -103,7 +103,7 @@ let expr_deps blocks vars deps defs x e =
103
103
| Closure (l , cont ) ->
104
104
List. iter l ~f: (fun x -> add_param_def vars defs x);
105
105
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)
107
107
| Field (y , _ ) -> add_dep deps x y
108
108
109
109
let program_deps { blocks; _ } =
@@ -152,7 +152,7 @@ let propagate1 deps defs st x =
152
152
var_set_lift
153
153
(fun z ->
154
154
match defs.(Var. idx z) with
155
- | Expr (Block (_ , a , _ )) when n < Array. length a ->
155
+ | Expr (Block (_ , a , _ , _ )) when n < Array. length a ->
156
156
let t = a.(n) in
157
157
add_dep deps x t;
158
158
Var.Tbl. get st t
@@ -186,15 +186,17 @@ type mutability_state =
186
186
; possibly_mutable : Code.Var.ISet .t
187
187
}
188
188
189
- let rec block_escape st x =
189
+ let rec block_escape st ?( immutable = false ) x =
190
190
Var.Set. iter
191
191
(fun y ->
192
192
if not (Code.Var.ISet. mem st.may_escape y)
193
193
then (
194
194
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
+
196
197
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)
198
200
| _ -> () ))
199
201
(Var.Tbl. get st.known_origins x)
200
202
@@ -226,15 +228,18 @@ let expr_escape st _x e =
226
228
| Pv v , `Shallow_const -> (
227
229
match st.defs.(Var. idx v) with
228
230
| 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)
230
235
| _ -> block_escape st v)
231
236
| Pv v , `Object_literal -> (
232
237
match st.defs.(Var. idx v) with
233
238
| Expr (Constant (Tuple _ )) -> ()
234
- | Expr (Block (_ , a , _ )) ->
239
+ | Expr (Block (_ , a , _ , _ )) ->
235
240
Array. iter a ~f: (fun x ->
236
241
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
238
243
| Expr (Constant _ ) -> ()
239
244
| _ -> block_escape st x)
240
245
| _ -> block_escape st v)
@@ -282,7 +287,7 @@ let propagate2 ?(skip_param = false) defs known_origins possibly_mutable st x =
282
287
|| Var.Set. exists
283
288
(fun z ->
284
289
match defs.(Var. idx z) with
285
- | Expr (Block (_ , a , _ )) ->
290
+ | Expr (Block (_ , a , _ , _ )) ->
286
291
n > = Array. length a
287
292
|| Var.ISet. mem possibly_mutable z
288
293
|| Var.Tbl. get st a.(n)
@@ -382,7 +387,7 @@ let direct_approx (info : Info.t) x =
382
387
then None
383
388
else
384
389
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)
386
391
| _ -> None )
387
392
None
388
393
(fun u v ->
@@ -392,6 +397,29 @@ let direct_approx (info : Info.t) x =
392
397
y
393
398
| _ -> None
394
399
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
+
395
423
let build_subst (info : Info.t ) vars =
396
424
let nv = Var. count () in
397
425
let subst = Array. init nv ~f: (fun i -> Var. of_idx i) in
0 commit comments