Skip to content

Commit ace3c0d

Browse files
committed
Tests: add more
1 parent 424344f commit ace3c0d

File tree

2 files changed

+215
-6
lines changed

2 files changed

+215
-6
lines changed

compiler/lib/generate_closure.ml

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -57,11 +57,14 @@ let rec collect_apply pc blocks visited tc ntc =
5757
| Some _ -> None)
5858
| _ -> None
5959
in
60-
let ntc =
61-
List.fold_left block.body ~init:ntc ~f:(fun acc x ->
60+
let visited, ntc =
61+
List.fold_left block.body ~init:(visited, ntc) ~f:(fun (visited, acc) x ->
6262
match x with
63-
| Let (_, Apply (z, _, _)) -> add_multi z pc acc
64-
| _ -> acc)
63+
| Let (_, Apply (z, _, _)) -> visited, add_multi z pc acc
64+
| Let (_, Closure (_, (pc, _))) ->
65+
let visited, _tc, ntc = collect_apply pc blocks visited tc ntc in
66+
visited, ntc
67+
| _ -> visited, acc)
6568
in
6669
match tc_opt with
6770
| Some tc -> visited, tc, ntc

compiler/tests-compiler/gh1007.ml

Lines changed: 208 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -312,7 +312,7 @@ end = struct
312312
in even i
313313

314314
let run () =
315-
for i = 0 to 10 do
315+
for i = 0 to 4 do
316316
ignore (even (i) : bool)
317317
done
318318
end
@@ -346,5 +346,211 @@ let () = M.run ()
346346
default:return 1 - (1 - even(1))}};
347347
even(i);
348348
var _a_=i + 1 | 0;
349-
if(10 !== i){var i=_a_;continue}
349+
if(4 !== i){var i=_a_;continue}
350350
return 0}} |}]
351+
352+
let%expect_test _ =
353+
let prog =
354+
{|
355+
module M : sig
356+
val run : unit -> unit
357+
end = struct
358+
let delayed = ref []
359+
let even i =
360+
let rec odd = function
361+
| 0 ->
362+
let f () = Printf.printf "in odd, called with %d\n" i in
363+
delayed := f :: !delayed;
364+
f ();
365+
false
366+
| 1 -> not (not (even 0))
367+
| 2 -> not (not (even 1))
368+
| n -> not (not (even (n - 1)))
369+
and even = function
370+
| 0 ->
371+
let f () = Printf.printf "in even, called with %d\n" i in
372+
delayed := f :: !delayed;
373+
f ();
374+
true
375+
| 1 -> not (not (odd 0))
376+
| 2 -> not (not (odd 1))
377+
| n -> not (not (odd (n - 1)))
378+
in even i
379+
380+
let run () =
381+
for i = 0 to 4 do
382+
ignore (even (i) : bool)
383+
done;
384+
List.iter (fun f -> f ()) (List.rev !delayed)
385+
end
386+
387+
let () = M.run ()
388+
|}
389+
in
390+
Util.compile_and_run prog;
391+
[%expect
392+
{|
393+
in even, called with 0
394+
in odd, called with 1
395+
in even, called with 2
396+
in odd, called with 3
397+
in even, called with 4
398+
in even, called with 0
399+
in odd, called with 1
400+
in even, called with 2
401+
in odd, called with 3
402+
in even, called with 4 |}];
403+
let program = Util.compile_and_parse prog in
404+
Util.print_fun_decl program (Some "run");
405+
[%expect
406+
{|
407+
function run(param)
408+
{var i=0;
409+
for(;;)
410+
{var
411+
closures=
412+
function(i)
413+
{function even(n)
414+
{if(2 < n >>> 0)return 1 - (1 - odd(n - 1 | 0));
415+
switch(n)
416+
{case 0:
417+
var f=function(param){return caml_call2(Stdlib_printf[2],_b_,i)};
418+
delayed[1] = [0,f,delayed[1]];
419+
f(0);
420+
return 1;
421+
case 1:return 1 - (1 - odd(0));
422+
default:return 1 - (1 - odd(1))}}
423+
function odd(n)
424+
{if(2 < n >>> 0)return 1 - (1 - even(n - 1 | 0));
425+
switch(n)
426+
{case 0:
427+
var f=function(param){return caml_call2(Stdlib_printf[2],_a_,i)};
428+
delayed[1] = [0,f,delayed[1]];
429+
f(0);
430+
return 0;
431+
case 1:return 1 - (1 - even(0));
432+
default:return 1 - (1 - even(1))}}
433+
var block=[0,even,odd];
434+
return block},
435+
closures$0=closures(i),
436+
even=closures$0[1];
437+
even(i);
438+
var _e_=i + 1 | 0;
439+
if(4 !== i){var i=_e_;continue}
440+
var
441+
_c_=caml_call1(Stdlib_list[9],delayed[1]),
442+
_d_=function(f){return caml_call1(f,0)};
443+
return caml_call2(Stdlib_list[15],_d_,_c_)}} |}]
444+
445+
let%expect_test _ =
446+
let prog =
447+
{|
448+
module M : sig
449+
val run : unit -> unit
450+
end = struct
451+
let delayed = ref []
452+
let even i =
453+
let rec odd = function
454+
| 0 -> `Cont (fun () ->
455+
let f () = Printf.printf "in odd, called with %d\n" i in
456+
delayed := f :: !delayed;
457+
f ();
458+
`Done false)
459+
| 1 -> `Cont (fun () -> even 0)
460+
| 2 -> `Cont (fun () -> even 1)
461+
| n -> `Cont (fun () -> even (n - 1))
462+
and even = function
463+
| 0 -> `Cont (fun () ->
464+
let f () = Printf.printf "in even, called with %d\n" i in
465+
delayed := f :: !delayed;
466+
f ();
467+
`Done true)
468+
| 1 -> `Cont (fun () -> odd 0)
469+
| 2 -> `Cont (fun () -> odd 1)
470+
| n -> `Cont (fun () -> odd (n - 1))
471+
in even i
472+
473+
let run () =
474+
for i = 0 to 4 do
475+
let rec r = function
476+
| `Done x -> x
477+
| `Cont f -> r (f ())
478+
in
479+
ignore (r (even (i)) : bool)
480+
done;
481+
List.iter (fun f -> f ()) (List.rev !delayed)
482+
end
483+
484+
let () = M.run ()
485+
|}
486+
in
487+
Util.compile_and_run prog;
488+
[%expect
489+
{|
490+
in even, called with 0
491+
in odd, called with 1
492+
in even, called with 2
493+
in odd, called with 3
494+
in even, called with 4
495+
in even, called with 0
496+
in odd, called with 1
497+
in even, called with 2
498+
in odd, called with 3
499+
in even, called with 4 |}];
500+
let program = Util.compile_and_parse prog in
501+
Util.print_fun_decl program (Some "run");
502+
[%expect
503+
{|
504+
function run(param$0)
505+
{var i=0;
506+
a:
507+
for(;;)
508+
{var
509+
closures=
510+
function(i)
511+
{function even(n)
512+
{if(2 < n >>> 0)
513+
return [0,748545554,function(param){return odd(n - 1 | 0)}];
514+
switch(n)
515+
{case 0:
516+
return [0,
517+
748545554,
518+
function(param)
519+
{function f(param)
520+
{return caml_call2(Stdlib_printf[2],_c_,i)}
521+
delayed[1] = [0,f,delayed[1]];
522+
f(0);
523+
return _d_}];
524+
case 1:return [0,748545554,function(param){return odd(0)}];
525+
default:return [0,748545554,function(param){return odd(1)}]}}
526+
function odd(n)
527+
{if(2 < n >>> 0)
528+
return [0,748545554,function(param){return even(n - 1 | 0)}];
529+
switch(n)
530+
{case 0:
531+
return [0,
532+
748545554,
533+
function(param)
534+
{function f(param)
535+
{return caml_call2(Stdlib_printf[2],_a_,i)}
536+
delayed[1] = [0,f,delayed[1]];
537+
f(0);
538+
return _b_}];
539+
case 1:return [0,748545554,function(param){return even(0)}];
540+
default:return [0,748545554,function(param){return even(1)}]}}
541+
var block=[0,even,odd];
542+
return block},
543+
closures$0=closures(i),
544+
even=closures$0[1],
545+
param=even(i),
546+
param$1=param;
547+
for(;;)
548+
{if(759635106 <= param$1[1])
549+
{var _g_=i + 1 | 0;
550+
if(4 !== i){var i=_g_;continue a}
551+
var
552+
_e_=caml_call1(Stdlib_list[9],delayed[1]),
553+
_f_=function(f){return caml_call1(f,0)};
554+
return caml_call2(Stdlib_list[15],_f_,_e_)}
555+
var f=param$1[2],param$2=caml_call1(f,0),param$1=param$2;
556+
continue}}} |}]

0 commit comments

Comments
 (0)