Skip to content

Commit 4bcdad6

Browse files
authored
Merge pull request #442 from bloomberg/bs_lambda
Bs lambda
2 parents e984329 + 299849e commit 4bcdad6

30 files changed

+546
-361
lines changed

jscomp/core.mllib

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ config_util
88

99

1010
lam
11-
lam_mk
1211
lam_print
1312
lam_compile_env
1413
lam_dispatch_primitive

jscomp/idents_analysis.ml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929

3030

3131

32-
module Ident_set = Lambda.IdentSet
32+
3333

3434
(*
3535
We have a current ident set

jscomp/idents_analysis.mli

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,4 +36,4 @@
3636
*)
3737

3838
val calculate_used_idents :
39-
(Ident.t, Lambda.IdentSet.t) Hashtbl.t -> Ident.t list -> Lambda.IdentSet.t
39+
(Ident.t, Ident_set.t) Hashtbl.t -> Ident.t list -> Ident_set.t

jscomp/lam.ml

Lines changed: 91 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -23,20 +23,36 @@
2323
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *)
2424

2525
type primitive = Lambda.primitive
26-
type switch = Lambda.lambda_switch =
26+
type switch =
2727
{ sw_numconsts: int;
2828
sw_consts: (int * t) list;
2929
sw_numblocks: int;
3030
sw_blocks: (int * t) list;
3131
sw_failaction : t option}
32-
and t = Lambda.lambda =
32+
and prim_info =
33+
{ primitive : primitive ;
34+
args : t list ;
35+
}
36+
and apply_info =
37+
{ fn : t ;
38+
args : t list ;
39+
loc : Location.t;
40+
status : Lambda.apply_status
41+
}
42+
and function_info =
43+
{ arity : int ;
44+
kind : Lambda.function_kind ;
45+
params : Ident.t list ;
46+
body : t
47+
}
48+
and t =
3349
| Lvar of Ident.t
3450
| Lconst of Lambda.structured_constant
35-
| Lapply of t * t list * Lambda.apply_info
36-
| Lfunction of Lambda.function_kind * Ident.t list * t
51+
| Lapply of apply_info
52+
| Lfunction of function_info
3753
| Llet of Lambda.let_kind * Ident.t * t * t
3854
| Lletrec of (Ident.t * t) list * t
39-
| Lprim of primitive * t list
55+
| Lprim of prim_info
4056
| Lswitch of t * switch
4157
| Lstringswitch of t * (string * t) list * t option
4258
| Lstaticraise of int * t list
@@ -100,9 +116,11 @@ type unop = t -> t
100116

101117
let var id : t = Lvar id
102118
let const ct : t = Lconst ct
103-
let apply fn args info : t = Lapply(fn,args, info)
104-
let function_ kind ids body : t =
105-
Lfunction(kind, ids, body)
119+
let apply fn args loc status : t =
120+
Lapply { fn; args; loc ;
121+
status }
122+
let function_ arity kind ids body : t =
123+
Lfunction { arity; kind; params = ids; body}
106124

107125
let let_ kind id e body : t
108126
= Llet (kind,id,e,body)
@@ -223,8 +241,8 @@ let lift_int32 b : t =
223241
let lift_int64 b : t =
224242
Lconst (Const_base (Const_int64 b))
225243

226-
let prim (prim : Prim.t) (ll : t list) : t =
227-
let default () : t = Lprim(prim,ll) in
244+
let prim (prim : Prim.t) (ll : t list) : t =
245+
let default () : t = Lprim { primitive = prim ;args = ll } in
228246
match ll with
229247
| [Lconst a] ->
230248
begin match prim, a with
@@ -366,9 +384,66 @@ let prim (prim : Prim.t) (ll : t list) : t =
366384

367385

368386
let not x : t =
369-
prim Pnot [x]
370-
371-
372-
let free_variables = Lambda.free_variables
373-
374-
let subst_lambda = Lambda.subst_lambda
387+
prim Pnot [x]
388+
389+
390+
let rec convert (lam : Lambda.lambda) : t =
391+
match lam with
392+
| Lvar x -> Lvar x
393+
| Lconst x ->
394+
Lconst x
395+
| Lapply (fn,args,info)
396+
-> apply (convert fn) (List.map convert args)
397+
info.apply_loc info.apply_status
398+
| Lfunction (kind, ids,body)
399+
-> function_ (List.length ids) kind ids (convert body)
400+
| Llet (kind,id,e,body)
401+
-> Llet(kind,id,convert e, convert body)
402+
| Lletrec (bindings,body)
403+
->
404+
Lletrec (List.map (fun (id, e) -> id, convert e) bindings, convert body)
405+
| Lprim (primitive,args)
406+
->
407+
Lprim {primitive ; args = List.map convert args }
408+
| Lswitch (e,s) ->
409+
Lswitch (convert e, convert_switch s)
410+
| Lstringswitch (e, cases, default) ->
411+
Lstringswitch (convert e, List.map (fun (x, b) -> x, convert b ) cases,
412+
match default with
413+
| None -> None
414+
| Some x -> Some (convert x)
415+
)
416+
417+
| Lstaticraise (id, args) ->
418+
Lstaticraise (id, List.map convert args)
419+
| Lstaticcatch (b, (i, ids), handler) ->
420+
Lstaticcatch (convert b, (i,ids), convert handler)
421+
| Ltrywith (b, id, handler) ->
422+
Ltrywith (convert b, id, convert handler)
423+
| Lifthenelse (b,then_,else_) ->
424+
Lifthenelse (convert b, convert then_, convert else_)
425+
| Lsequence (a,b)
426+
-> Lsequence (convert a, convert b)
427+
| Lwhile (b,body) ->
428+
Lwhile (convert b, convert body)
429+
| Lfor (id, from_, to_, dir, loop) ->
430+
Lfor (id, convert from_, convert to_, dir, convert loop)
431+
| Lassign (id, body) ->
432+
Lassign (id, convert body)
433+
| Lsend (kind, a,b,ls, loc) ->
434+
Lsend(kind, convert a, convert b, List.map convert ls, loc )
435+
436+
| Levent (e, event) ->
437+
Levent (convert e, event)
438+
| Lifused (id, e) -> Lifused(id, convert e)
439+
440+
and convert_switch (s : Lambda.lambda_switch) : switch =
441+
{ sw_numconsts = s.sw_numconsts ;
442+
sw_consts = List.map (fun (i, lam) -> i, convert lam) s.sw_consts;
443+
sw_numblocks = s.sw_numblocks;
444+
sw_blocks = List.map (fun (i,lam) -> i, convert lam ) s.sw_blocks;
445+
sw_failaction =
446+
match s.sw_failaction with
447+
| None -> None
448+
| Some a -> Some (convert a)
449+
}

jscomp/lam.mli

Lines changed: 32 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -25,20 +25,37 @@
2525
type primitive = Lambda.primitive
2626

2727

28-
type switch = Lambda.lambda_switch =
28+
type switch =
2929
{ sw_numconsts: int;
3030
sw_consts: (int * t) list;
3131
sw_numblocks: int;
3232
sw_blocks: (int * t) list;
3333
sw_failaction : t option}
34-
and t = Lambda.lambda = private
34+
and apply_info = private
35+
{ fn : t ;
36+
args : t list ;
37+
loc : Location.t;
38+
status : Lambda.apply_status
39+
}
40+
41+
and prim_info = private
42+
{ primitive : primitive ;
43+
args : t list ;
44+
}
45+
and function_info = private
46+
{ arity : int ;
47+
kind : Lambda.function_kind ;
48+
params : Ident.t list ;
49+
body : t
50+
}
51+
and t = private
3552
| Lvar of Ident.t
3653
| Lconst of Lambda.structured_constant
37-
| Lapply of t * t list * Lambda.apply_info
38-
| Lfunction of Lambda.function_kind * Ident.t list * t
54+
| Lapply of apply_info
55+
| Lfunction of function_info
3956
| Llet of Lambda.let_kind * Ident.t * t * t
4057
| Lletrec of (Ident.t * t) list * t
41-
| Lprim of primitive * t list
58+
| Lprim of prim_info
4259
| Lswitch of t * switch
4360
| Lstringswitch of t * (string * t) list * t option
4461
| Lstaticraise of int * t list
@@ -70,8 +87,9 @@ type unop = t -> t
7087

7188
val var : Ident.t -> t
7289
val const : Lambda.structured_constant -> t
73-
val apply : t -> t list -> Lambda.apply_info -> t
74-
val function_ : Lambda.function_kind -> Ident.t list -> t -> t
90+
91+
val apply : t -> t list -> Location.t -> Lambda.apply_status -> t
92+
val function_ : int -> Lambda.function_kind -> Ident.t list -> t -> t
7593
val let_ : Lambda.let_kind -> Ident.t -> t -> t -> t
7694
val letrec : (Ident.t * t) list -> t -> t
7795
val if_ : triop
@@ -96,7 +114,9 @@ val send :
96114
Lambda.meth_kind ->
97115
t -> t -> t list ->
98116
Location.t -> t
99-
val prim : Lambda.primitive -> t list -> t
117+
118+
val prim : Lambda.primitive -> t list -> t
119+
100120
val staticcatch :
101121
t -> int * Ident.t list -> t -> t
102122

@@ -108,6 +128,8 @@ val for_ :
108128
t ->
109129
t -> Asttypes.direction_flag -> t -> t
110130

111-
val free_variables : t -> Lambda.IdentSet.t
112131

113-
val subst_lambda : t Ident.tbl -> t -> t
132+
133+
134+
135+
val convert : Lambda.lambda -> t

jscomp/lam_analysis.ml

Lines changed: 21 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ let rec no_side_effects (lam : Lam.t) : bool =
3232
| Lvar _
3333
| Lconst _
3434
| Lfunction _ -> true
35-
| Lprim (primitive, args) ->
35+
| Lprim {primitive; args; _} ->
3636
List.for_all no_side_effects args &&
3737
(
3838
match primitive with
@@ -186,10 +186,12 @@ let rec no_side_effects (lam : Lam.t) : bool =
186186
if it [Not_found], there are no other exceptions
187187
can be thrown
188188
*)
189-
| Ltrywith (Lprim(Pccall{prim_name = "caml_sys_getenv"},
190-
[Lconst _]),exn,
191-
Lifthenelse(Lprim(_, [Lvar exn1;
192-
Lprim(Pgetglobal ({name="Not_found"}),[])]),
189+
| Ltrywith (Lprim { primitive = Pccall{prim_name = "caml_sys_getenv"};
190+
args = [Lconst _]; _},exn,
191+
Lifthenelse(Lprim{args =
192+
[Lvar exn1;
193+
Lprim {primitive = Pgetglobal ({name="Not_found"}); args = []; _}]
194+
; _},
193195
then_, _)) when Ident.same exn1 exn
194196
(** we might put this in an optimization pass
195197
also make sure when we wrap this in [js] we
@@ -234,11 +236,13 @@ let rec size (lam : Lam.t) =
234236
| Lconst c -> size_constant c
235237
| Llet(_, _, l1, l2) -> 1 + size l1 + size l2
236238
| Lletrec _ -> really_big ()
237-
| Lprim(Pfield _, [Lprim(Pgetglobal _, [ ])])
239+
| Lprim{primitive = Pfield _;
240+
args = [Lprim { primitive = Pgetglobal _; args = [ ]; _}]
241+
; _}
238242
-> 1
239-
| Lprim (Praise _, [l ])
243+
| Lprim {primitive = Praise _; args = [l ]; _}
240244
-> size l
241-
| Lprim(_, ll) -> size_lams 1 ll
245+
| Lprim {args = ll; _} -> size_lams 1 ll
242246

243247
(** complicated
244248
1. inline this function
@@ -248,10 +252,10 @@ let rec size (lam : Lam.t) =
248252
{var $$let=Make(funarg);
249253
return [0, $$let[5],... $$let[16]]}
250254
*)
251-
| Lapply(f,
252-
args, _) -> size_lams (size f) args
255+
| Lapply{ fn;
256+
args; _} -> size_lams (size fn) args
253257
(* | Lfunction(_, params, l) -> really_big () *)
254-
| Lfunction(_,_params,body) -> size body
258+
| Lfunction {body} -> size body
255259
| Lswitch(_, _) -> really_big ()
256260
| Lstringswitch(_,_,_) -> really_big ()
257261
| Lstaticraise (i,ls) ->
@@ -290,15 +294,16 @@ let rec eq_lambda (l1 : Lam.t) (l2 : Lam.t) =
290294
match (l1, l2) with
291295
| Lvar i1, Lvar i2 -> Ident.same i1 i2
292296
| Lconst c1, Lconst c2 -> c1 = c2 (* *)
293-
| Lapply (l1,args1,_), Lapply(l2,args2,_) ->
297+
| Lapply {fn = l1; args = args1; _}, Lapply {fn = l2; args = args2; _} ->
294298
eq_lambda l1 l2 && List.for_all2 eq_lambda args1 args2
295299
| Lfunction _ , Lfunction _ -> false (* TODO -- simple functions ?*)
296300
| Lassign(v0,l0), Lassign(v1,l1) -> Ident.same v0 v1 && eq_lambda l0 l1
297301
| Lstaticraise(id,ls), Lstaticraise(id1,ls1) ->
298302
id = id1 && List.for_all2 eq_lambda ls ls1
299303
| Llet (_,_,_,_), Llet (_,_,_,_) -> false
300304
| Lletrec _, Lletrec _ -> false
301-
| Lprim (p,ls), Lprim (p1,ls1) ->
305+
| Lprim {primitive = p; args = ls; } ,
306+
Lprim {primitive = p1; args = ls1} ->
302307
eq_primitive p p1 && List.for_all2 eq_lambda ls ls1
303308
| Lswitch _, Lswitch _ -> false
304309
| Lstringswitch _ , Lstringswitch _ -> false
@@ -397,14 +402,14 @@ let free_variables (export_idents : Ident_set.t ) (params : stats Ident_map.t )
397402
match lam with
398403
| Lvar v -> map_use top v
399404
| Lconst _ -> ()
400-
| Lapply(fn, args, _) ->
405+
| Lapply {fn; args; _} ->
401406
iter top fn;
402407
let top = new_env fn top in
403408
List.iter (iter top ) args
404-
| Lprim(_p, args) ->
409+
| Lprim {args ; _} ->
405410
(* Check: can top be propoaged for all primitives *)
406411
List.iter (iter top) args
407-
| Lfunction(_kind, params, body) ->
412+
| Lfunction{ params; body} ->
408413
local_add_list params;
409414
iter no_substitute body
410415
| Llet(_let_kind, id, arg, body) ->

0 commit comments

Comments
 (0)