@@ -245,8 +245,14 @@ and compile_let flag (cxt : Lam_compile_defs.cxt) id (arg : Lambda.lambda) : Js
245
245
match flag, arg with
246
246
| let_kind , _ ->
247
247
compile_lambda {cxt with st = Declare (let_kind, id); should_return = False } arg
248
-
249
- and compile_recursive_let (cxt : Lam_compile_defs.cxt ) (id : Ident.t ) (arg : Lambda.lambda ) =
248
+ (* *
249
+ The second return values are values which need to be wrapped using
250
+ [caml_update_dummy]
251
+ *)
252
+ and compile_recursive_let
253
+ (cxt : Lam_compile_defs.cxt )
254
+ (id : Ident.t )
255
+ (arg : Lambda.lambda ) : Js_output.t * Ident.t list =
250
256
match arg with
251
257
| Lfunction (kind , params , body ) ->
252
258
(* Invariant: jmp_table can not across function boundary,
@@ -296,7 +302,25 @@ and compile_recursive_let (cxt : Lam_compile_defs.cxt) (id : Ident.t) (arg : Lam
296
302
else (* TODO: save computation of length several times *)
297
303
E. fun_ params (Js_output. to_block output )
298
304
), []
299
- | (Lprim(Pmakeblock _ , _ ) ) ->
305
+ | Lprim (Pmakeblock (0 , _, _) , ls)
306
+ when List. for_all (function | Lambda. Lvar _ -> true | _ -> false ) ls
307
+ ->
308
+ (* capture cases like for {!Queue}
309
+ {[let rec cell = { content = x; next = cell} ]}
310
+ *)
311
+ Js_output. of_block (
312
+ S. define ~kind: Variable id (E. arr Mutable [] ) ::
313
+ (List. mapi (fun i x ->
314
+ match x with
315
+ | Lambda. Lvar lid
316
+ -> S. exp
317
+ (Js_array. set_array (E. var id) (E. int (Int32. of_int i)) (E. var lid))
318
+ | _ -> assert false
319
+ ) ls)
320
+ ), []
321
+
322
+ | Lprim (Pmakeblock _ , _ ) ->
323
+ (* FIXME: also should fill tag *)
300
324
(* Lconst should not appear here if we do [scc]
301
325
optimization, since it's faked recursive value,
302
326
however it would affect scope issues, we have to declare it first
@@ -308,8 +332,12 @@ and compile_recursive_let (cxt : Lam_compile_defs.cxt) (id : Ident.t) (arg : Lam
308
332
(* TODO: check recursive value ..
309
333
could be improved for simple cases
310
334
*)
311
- Js_output. of_block (
312
- b @ [S. exp(E. runtime_call Js_config. obj_runtime " caml_update_dummy" [ E. var id; v])]),
335
+ Js_output. of_block
336
+ (
337
+ b @
338
+ [S. exp
339
+ (E. runtime_call Js_config. obj_runtime " caml_update_dummy"
340
+ [ E. var id; v])]),
313
341
[id]
314
342
(* S.define ~kind:Variable id (E.arr Mutable []):: *)
315
343
| _ -> assert false
0 commit comments