Skip to content

Commit 93c0a04

Browse files
committed
Compiler: prepare compiler for 1658
1 parent 0b995da commit 93c0a04

File tree

5 files changed

+42
-29
lines changed

5 files changed

+42
-29
lines changed

compiler/lib/effects.ml

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -543,11 +543,11 @@ let cps_block ~st ~k pc block =
543543
in
544544

545545
let rewrite_instr x e =
546-
let perform_effect ~effect_ ~continuation =
546+
let perform_effect ~effect_ ~continuation ~tail =
547547
Some
548548
(fun ~k ->
549549
let e =
550-
Prim (Extern "caml_perform_effect", [ Pv effect_; continuation; Pv k ])
550+
Prim (Extern "caml_perform_effect", [ Pv effect_; continuation; tail; Pv k ])
551551
in
552552
let x = Var.fresh () in
553553
[ Let (x, e) ], Return x)
@@ -560,22 +560,26 @@ let cps_block ~st ~k pc block =
560560
exact || Global_flow.exact_call st.flow_info f (List.length args)
561561
in
562562
tail_call ~st ~exact ~in_cps:true ~check:true ~f (args @ [ k ]))
563-
| Prim (Extern "%resume", [ Pv stack; Pv f; Pv arg ]) ->
563+
| Prim (Extern "%resume", [ Pv stack; Pv f; Pv arg; tail ]) ->
564564
Some
565565
(fun ~k ->
566566
let k' = Var.fresh_n "cont" in
567567
tail_call
568568
~st
569-
~instrs:[ Let (k', Prim (Extern "caml_resume_stack", [ Pv stack; Pv k ])) ]
569+
~instrs:
570+
[ Let (k', Prim (Extern "caml_resume_stack", [ Pv stack; tail; Pv k ])) ]
570571
~exact:(Global_flow.exact_call st.flow_info f 1)
571572
~in_cps:true
572573
~check:true
573574
~f
574575
[ arg; k' ])
575576
| Prim (Extern "%perform", [ Pv effect_ ]) ->
576-
perform_effect ~effect_ ~continuation:(Pc (Int Targetint.zero))
577-
| Prim (Extern "%reperform", [ Pv effect_; continuation ]) ->
578-
perform_effect ~effect_ ~continuation
577+
perform_effect
578+
~effect_
579+
~continuation:(Pc (Int Targetint.zero))
580+
~tail:(Pc (Int Targetint.zero))
581+
| Prim (Extern "%reperform", [ Pv effect_; continuation; tail ]) ->
582+
perform_effect ~effect_ ~continuation ~tail
579583
| _ -> None
580584
in
581585

compiler/lib/parse_bytecode.ml

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2368,7 +2368,6 @@ and compile infos pc state (instrs : instr list) =
23682368
let func = State.peek 0 state in
23692369
let arg = State.peek 1 state in
23702370
let x, state = State.fresh_var state in
2371-
23722371
if debug_parser ()
23732372
then
23742373
Format.printf
@@ -2381,23 +2380,30 @@ and compile infos pc state (instrs : instr list) =
23812380
func
23822381
Var.print
23832382
arg;
2384-
let state =
2383+
let state, tail =
23852384
match Ocaml_version.compare Ocaml_version.current [ 5; 2 ] < 0 with
2386-
| true -> State.pop 2 state
2387-
| false -> State.pop 3 state
2385+
| true -> State.pop 2 state, Pc (Int (Targetint.of_int_exn 0))
2386+
| false ->
2387+
let tail = State.peek 2 state in
2388+
State.pop 3 state, Pv tail
23882389
in
2389-
23902390
compile
23912391
infos
23922392
(pc + 1)
23932393
state
2394-
(Let (x, Prim (Extern "%resume", [ Pv stack; Pv func; Pv arg ])) :: instrs)
2394+
(Let (x, Prim (Extern "%resume", [ Pv stack; Pv func; Pv arg; tail ])) :: instrs)
23952395
| RESUMETERM ->
23962396
let stack = State.accu state in
23972397
let func = State.peek 0 state in
23982398
let arg = State.peek 1 state in
23992399
let x, state = State.fresh_var state in
2400-
2400+
let tail =
2401+
match Ocaml_version.compare Ocaml_version.current [ 5; 2 ] < 0 with
2402+
| true -> Pc (Int (Targetint.of_int_exn 0))
2403+
| false ->
2404+
let tail = State.peek 2 state in
2405+
Pv tail
2406+
in
24012407
if debug_parser ()
24022408
then
24032409
Format.printf
@@ -2408,7 +2414,7 @@ and compile infos pc state (instrs : instr list) =
24082414
func
24092415
Var.print
24102416
arg;
2411-
( Let (x, Prim (Extern "%resume", [ Pv stack; Pv func; Pv arg ])) :: instrs
2417+
( Let (x, Prim (Extern "%resume", [ Pv stack; Pv func; Pv arg; tail ])) :: instrs
24122418
, Return x
24132419
, state )
24142420
| PERFORM ->
@@ -2425,13 +2431,13 @@ and compile infos pc state (instrs : instr list) =
24252431
| REPERFORMTERM ->
24262432
let eff = State.accu state in
24272433
let stack = State.peek 0 state in
2428-
(* We don't need [State.peek 1 state] *)
2434+
let tail = State.peek 1 state in
24292435
let state = State.pop 2 state in
24302436
let x, state = State.fresh_var state in
24312437

24322438
if debug_parser ()
24332439
then Format.printf "return reperform(%a, %a)@." Var.print eff Var.print stack;
2434-
( Let (x, Prim (Extern "%reperform", [ Pv eff; Pv stack ])) :: instrs
2440+
( Let (x, Prim (Extern "%reperform", [ Pv eff; Pv stack; Pv tail ])) :: instrs
24352441
, Return x
24362442
, state )
24372443
| EVENT | BREAK | FIRST_UNIMPLEMENTED_OP -> assert false)

runtime/js/effect.js

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ var caml_fiber_stack;
7878
//Provides:caml_resume_stack
7979
//Requires: caml_named_value, caml_raise_constant, caml_exn_stack, caml_fiber_stack
8080
//If: effects
81-
function caml_resume_stack(stack, k) {
81+
function caml_resume_stack(stack, last, k) {
8282
if (!stack)
8383
caml_raise_constant(
8484
caml_named_value("Effect.Continuation_already_resumed"),
@@ -111,9 +111,9 @@ function caml_pop_fiber() {
111111
//Provides: caml_perform_effect
112112
//Requires: caml_pop_fiber, caml_stack_check_depth, caml_trampoline_return, caml_exn_stack, caml_fiber_stack
113113
//If: effects
114-
function caml_perform_effect(eff, cont, k0) {
114+
function caml_perform_effect(eff, cont, last, k0) {
115115
// Allocate a continuation if we don't already have one
116-
if (!cont) cont = [245 /*continuation*/, 0];
116+
if (!cont) cont = [245 /*continuation*/, 0, 0];
117117
// Get current effect handler
118118
var handler = caml_fiber_stack.h[3];
119119
// Cons the current fiber onto the continuation:
@@ -122,9 +122,10 @@ function caml_perform_effect(eff, cont, k0) {
122122
// Move to parent fiber and execute the effect handler there
123123
// The handler is defined in Stdlib.Effect, so we know that the arity matches
124124
var k1 = caml_pop_fiber();
125+
var last_fiber = "last_fiber"; // FIXME
125126
return caml_stack_check_depth()
126-
? handler(eff, cont, k1, k1)
127-
: caml_trampoline_return(handler, [eff, cont, k1, k1]);
127+
? handler(eff, cont, last_fiber, k1)
128+
: caml_trampoline_return(handler, [eff, cont, last_fiber, k1]);
128129
}
129130

130131
//Provides: caml_alloc_stack

runtime/js/jslib.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -86,9 +86,9 @@ var caml_callback = caml_call_gen;
8686
//Requires:caml_stack_depth, caml_call_gen, caml_exn_stack, caml_fiber_stack, caml_wrap_exception, caml_resume_stack, caml_fresh_oo_id, caml_named_value, caml_raise_with_arg, caml_string_of_jsbytes
8787
//Requires: caml_raise_constant
8888
function caml_callback(f, args) {
89-
function uncaught_effect_handler(eff, k, ms) {
89+
function uncaught_effect_handler(eff, k, last, ms) {
9090
// Resumes the continuation k by raising exception Unhandled.
91-
caml_resume_stack(k[1], ms);
91+
caml_resume_stack(k[1], last, ms);
9292
var exn = caml_named_value("Effect.Unhandled");
9393
if (exn) caml_raise_with_arg(exn, eff);
9494
else {

runtime/wasm/effect.wat

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -218,7 +218,7 @@
218218
(data $already_resumed "Effect.Continuation_already_resumed")
219219

220220
(func (export "%resume")
221-
(param $stack (ref eq)) (param $f (ref eq)) (param $v (ref eq))
221+
(param $stack (ref eq)) (param $f (ref eq)) (param $v (ref eq)) (param $tail (ref eq))
222222
(result (ref eq))
223223
(local $k (ref $cont))
224224
(local $pair (ref $pair))
@@ -297,7 +297,7 @@
297297
(struct.get $cont $cont_func (local.get $k1))))
298298

299299
(func $reperform (export "%reperform")
300-
(param $eff (ref eq)) (param $cont (ref eq))
300+
(param $eff (ref eq)) (param $cont (ref eq)) (param $tail (ref eq))
301301
(result (ref eq))
302302
(return_call $capture_continuation
303303
(ref.func $do_perform)
@@ -306,7 +306,8 @@
306306
(func (export "%perform") (param $eff (ref eq)) (result (ref eq))
307307
(return_call $reperform (local.get $eff)
308308
(array.new_fixed $block 3 (ref.i31 (global.get $cont_tag))
309-
(ref.i31 (i32.const 0)) (ref.i31 (i32.const 0)))))
309+
(ref.i31 (i32.const 0)) (ref.i31 (i32.const 0)))
310+
(ref.i31 (i32.const 0))))
310311

311312
;; Allocate a stack
312313

@@ -614,7 +615,7 @@
614615
(struct.get $cps_fiber $cont (local.get $top)))
615616

616617
(func $caml_resume_stack (export "caml_resume_stack")
617-
(param $vstack (ref eq)) (param $k (ref eq)) (result (ref eq))
618+
(param $vstack (ref eq)) (param $last (ref eq)) (param $k (ref eq)) (result (ref eq))
618619
(local $stack (ref $cps_fiber))
619620
(drop (block $already_resumed (result (ref eq))
620621
(local.set $stack
@@ -644,7 +645,7 @@
644645
(ref.i31 (i32.const 0)))
645646

646647
(func (export "caml_perform_effect")
647-
(param $eff (ref eq)) (param $vcont (ref eq)) (param $k0 (ref eq))
648+
(param $eff (ref eq)) (param $vcont (ref eq)) (param $last (ref eq)) (param $k0 (ref eq))
648649
(result (ref eq))
649650
(local $handlers (ref $handlers))
650651
(local $handler (ref eq)) (local $k1 (ref eq))
@@ -727,6 +728,7 @@
727728
(call $caml_resume_stack
728729
(array.get $block
729730
(ref.cast (ref $block) (local.get $k)) (i32.const 1))
731+
(ref.i31 (i32.const 0))
730732
(local.get $ms)))
731733
(call $raise_unhandled (local.get $eff) (ref.i31 (i32.const 0))))
732734

0 commit comments

Comments
 (0)