Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: parenthetical syntax for cycles, timeout etc. #4608

Draft
wants to merge 137 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 134 commits
Commits
Show all changes
137 commits
Select commit Hold shift + click to select a range
d4811e2
WIP: surface syntax for parentheticals
ggreif Jul 10, 2024
b6d32ec
WIP: first AST modifications
ggreif Jul 10, 2024
d3b9415
WIP: augment IR too
ggreif Jul 10, 2024
3f57777
Update src/mo_frontend/definedness.ml
ggreif Jul 10, 2024
7e23ac8
WIP: fill the parenthetical
ggreif Jul 10, 2024
b0516b0
tweaks
ggreif Jul 10, 2024
dc5a72f
define and use `tupVarsP` helper
ggreif Jul 10, 2024
8f7df27
teach about `SystemCyclesAddPrim`
ggreif Jul 10, 2024
e5f3ca9
examine all exprs
ggreif Jul 10, 2024
5eb79a3
WIP: doing naughty stuff
ggreif Jul 10, 2024
9672a96
WIP: this starts working
ggreif Jul 10, 2024
00b2507
accept
ggreif Jul 10, 2024
3d4bb5a
cleanup
ggreif Jul 10, 2024
d989397
compress
ggreif Jul 10, 2024
892ea54
WIP: prepare `ICCallPrim` to carry setup code
ggreif Jul 11, 2024
42a0471
WIP: compile the setup code
ggreif Jul 11, 2024
e43b1cc
elim a FIXME
ggreif Jul 11, 2024
43e816c
minor refactor
ggreif Jul 11, 2024
272870b
Merge branch 'master' into gabor/parentheticals
ggreif Jul 11, 2024
2f22db2
explain more cycles
ggreif Jul 11, 2024
b6ee8dd
remove because redundant
ggreif Jul 11, 2024
812d78d
fix IR renaming
ggreif Jul 11, 2024
e7f13f6
cleanup
ggreif Jul 11, 2024
ccd03db
tweaks
ggreif Jul 11, 2024
dbe054d
tweak
ggreif Jul 14, 2024
835502c
generate less lambdas on the fly
ggreif Jul 14, 2024
b104f85
integrate also the invocation of the `unary_async`
ggreif Jul 14, 2024
0542367
Merge branch 'master' into gabor/parentheticals
ggreif Jul 17, 2024
eaa577d
merge corrections
ggreif Jul 17, 2024
4f77084
WIP: start defining prims
ggreif Jul 17, 2024
38dfd70
WIP: `CPSAsync`
ggreif Jul 17, 2024
1f61bb5
WIP: begin fleshing out receiving
ggreif Jul 18, 2024
4d0d263
WIP: draft codegen for `ICCyclesPrim`
ggreif Jul 18, 2024
d472f53
WIP: yes, it expodes!
ggreif Jul 18, 2024
48096cb
actually send the parenthetical
ggreif Jul 18, 2024
ff217f3
tweak
ggreif Jul 19, 2024
29110d3
interpret `ICCallerPrim` as non-informative
ggreif Jul 19, 2024
463f12a
Merge branch 'master' into gabor/parentheticals
ggreif Jul 27, 2024
4abc9e8
WIP: pass a pair
ggreif Jul 30, 2024
261ae02
simplify
ggreif Aug 5, 2024
2e5b787
restrict pair creation
ggreif Aug 5, 2024
8c05650
futures only
ggreif Aug 5, 2024
f9abea4
simplifying folds
ggreif Aug 5, 2024
998f689
WIP: prepare `ICCyclesPrim` for all possibilities
ggreif Aug 5, 2024
6873747
tweak
ggreif Aug 5, 2024
3f4c1de
tweak
ggreif Aug 5, 2024
009f05d
tweak
ggreif Aug 5, 2024
2bbe8d5
WIP: this ccompiles
ggreif Aug 6, 2024
391fedd
fix
ggreif Aug 6, 2024
275e952
wip
ggreif Aug 6, 2024
56d79fe
impl. type-checking
ggreif Aug 6, 2024
4009982
WIP: pass cycles
ggreif Aug 6, 2024
8628695
WIP: crash is fixed
ggreif Aug 6, 2024
016ac58
fix up `ICCyclesPrim`'s type
ggreif Aug 6, 2024
9c611a9
remove legacy `Cycles.add`
ggreif Aug 6, 2024
ee4e2c9
WIP: allow decorations on `AsyncE`
ggreif Aug 7, 2024
4279b96
arrange parenthetical
ggreif Aug 7, 2024
0f35682
WIP: compiles
ggreif Aug 7, 2024
5a9e300
Merge branch 'master' into gabor/parentheticals
ggreif Aug 9, 2024
3d5cdc7
Merge branch 'master' into gabor/parentheticals
ggreif Aug 12, 2024
e080bcb
wip
ggreif Aug 8, 2024
3120931
merge fix
ggreif Aug 12, 2024
cf7cfa4
fix up test, but legacy should still work
ggreif Aug 12, 2024
84e42e1
infer parenthetical
ggreif Aug 12, 2024
b3ea1c2
WIP: test
ggreif Aug 12, 2024
6b0d54a
handle stacked parenthetials
ggreif Aug 12, 2024
ebc89b4
WIP: make it an option
ggreif Aug 13, 2024
82f2049
WIP: thread parentheticals through for `async`
ggreif Aug 13, 2024
a7d2874
make sure that the record has a `cycles` field
ggreif Aug 13, 2024
b482532
maybe we should rule this out
ggreif Aug 14, 2024
13b46f6
remove FIXMEs
ggreif Aug 14, 2024
b5f98a9
elim FIXMEs
ggreif Aug 14, 2024
19e8058
elim FIXMEs
ggreif Aug 14, 2024
a0e321d
elim FIXMEs
ggreif Aug 14, 2024
d147896
elim FIXMEs
ggreif Aug 14, 2024
a23f97a
elim FIXMEs
ggreif Aug 14, 2024
c475dc7
tweak
ggreif Aug 14, 2024
58c81b9
elim FIXMEs
ggreif Aug 14, 2024
498dd9b
elim FIXMEs
ggreif Aug 14, 2024
41186f3
merge `master`
ggreif Oct 21, 2024
65013fa
add `M0200`
ggreif Oct 22, 2024
2f179ec
start with a coarse warning
ggreif Oct 22, 2024
2f938cb
say what attribute is it
ggreif Oct 23, 2024
38fb28c
check `cycles` attribute type
ggreif Oct 23, 2024
031c375
cleanup
ggreif Oct 23, 2024
ac6928c
validate `async` exprs too
ggreif Oct 23, 2024
b9b3c17
accept
ggreif Oct 23, 2024
fbaf8b4
exercise `M0200` too
ggreif Oct 23, 2024
599fe2d
WIP: fire&forget doesn't work yet
ggreif Oct 24, 2024
30dbe01
apply parenthetical to one-shot sends
ggreif Nov 14, 2024
5be4240
start with tests for `call_raw`
ggreif Nov 14, 2024
a5b0984
tweaks
ggreif Nov 15, 2024
137ab9a
WIP: fix problem with `Cycles.add` not sticking
ggreif Nov 15, 2024
2b27bf9
eliminate a warning
ggreif Nov 29, 2024
92976f8
remove warnings
ggreif Nov 29, 2024
336de0b
simplify
ggreif Nov 29, 2024
8a7c490
WIP: try to warn on non-send calls
ggreif Nov 29, 2024
05eb145
fix M0202
ggreif Nov 29, 2024
0a9f6c0
fix warnings
ggreif Nov 29, 2024
fb97b74
warn empty notes
ggreif Nov 30, 2024
fe6107e
tweaks
ggreif Nov 30, 2024
277789a
what did I think here?
ggreif Dec 2, 2024
2a2b19a
Apply suggestions from code review
ggreif Dec 2, 2024
85075eb
don't arrange trivial parentheticals
ggreif Dec 2, 2024
1982b48
put the parenthetical in front
ggreif Dec 2, 2024
a93b8e1
Update src/ir_def/arrange_ir.ml
ggreif Dec 2, 2024
5a4d21f
Merge branch 'master' into gabor/parentheticals
ggreif Dec 2, 2024
9ae719b
Merge branch 'master' into gabor/parentheticals
ggreif Dec 3, 2024
f0f9436
test both old and new style
ggreif Dec 3, 2024
21ce382
accept
ggreif Dec 3, 2024
fff0aca
disable `drun-eop-*` for now
ggreif Dec 3, 2024
df56dcc
tidy up
ggreif Dec 3, 2024
b7aab76
be more explicit with `AsyncE()`
ggreif Dec 3, 2024
4ba0df1
simplify
ggreif Dec 3, 2024
8384150
function-body `CPSAsync(Fut)` should ignore the cycle send note on it
ggreif Dec 3, 2024
360974a
tweaks
ggreif Dec 3, 2024
309a231
fix `cps_asyncE` for the `AsyncE` (freestanding) case
ggreif Dec 3, 2024
64696a1
explicitly zero `cycles` when user doesn't specify any
ggreif Dec 3, 2024
339a98e
Merge branch 'master' into gabor/parentheticals
ggreif Dec 6, 2024
a0d475a
add new API
ggreif Dec 6, 2024
c9bd84f
WIP: prepare for `timeout`
ggreif Dec 6, 2024
3bed728
WIP: `replyDeadline` is still 0
ggreif Dec 6, 2024
cbfacdf
check for `timeout` type error
ggreif Dec 6, 2024
f1cc907
intro `nat32`
ggreif Dec 6, 2024
2edbcd9
WIP: begin checking `timeout`
ggreif Dec 6, 2024
83e70ab
WIP: invoke `call_with_best_effort_response`
ggreif Dec 7, 2024
0878d90
access at the correct type
ggreif Dec 7, 2024
ec31258
break out `infer_check_bases_fields` and use it to check just a few s…
ggreif Dec 10, 2024
ca66302
some errors are now emitted in a centralised fashion
ggreif Dec 10, 2024
4c37385
tweaks
ggreif Dec 10, 2024
e79c48d
intro and use `SystemTimeoutPrim`
ggreif Dec 10, 2024
b5eb704
accept
ggreif Dec 10, 2024
f80ffa8
fix warning
ggreif Dec 10, 2024
2e58517
unfake, but beware of the duplication!
ggreif Dec 10, 2024
7cb6cf0
WIP: `timeout` for one-shot calls
ggreif Dec 10, 2024
dc37044
`oneshot` tests actually work!
ggreif Dec 10, 2024
72900db
Merge branch 'master' into gabor/parentheticals
ggreif Dec 23, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -512,8 +512,8 @@ rec {
drun-compacting-gc = snty_compacting_gc_subdir "run-drun" [ moc nixpkgs.drun ] ;
drun-generational-gc = snty_generational_gc_subdir "run-drun" [ moc nixpkgs.drun ] ;
drun-incremental-gc = snty_incremental_gc_subdir "run-drun" [ moc nixpkgs.drun ] ;
drun-eop-release = enhanced_orthogonal_persistence_subdir "run-drun" [ moc nixpkgs.drun ] ;
drun-eop-debug = snty_enhanced_orthogonal_persistence_subdir "run-drun" [ moc nixpkgs.drun ] ;
## FOR NOW drun-eop-release = enhanced_orthogonal_persistence_subdir "run-drun" [ moc nixpkgs.drun ] ;
## FOR NOW drun-eop-debug = snty_enhanced_orthogonal_persistence_subdir "run-drun" [ moc nixpkgs.drun ] ;
Comment on lines +515 to +516
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

don't forget to revert

fail = test_subdir "fail" [ moc ];
fail-eop = enhanced_orthogonal_persistence_subdir "fail" [ moc ];
repl = test_subdir "repl" [ moc ];
Expand Down
1 change: 1 addition & 0 deletions doc/md/examples/grammar.txt
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,7 @@
'break' <id> <exp_nullary>?
'continue' <id>
'debug' <exp_nest>
'(' <exp_post>? 'with' <list(<exp_field>, ';')> ')' <exp_nest>
Copy link
Contributor

@rvanasa rvanasa Oct 28, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thoughts on using , here in place of ; for consistency with other parenthesized expressions? The formatter uses this invariant (commas in parentheses, semicolons in square brackets and curly braces) to automatically replace commas with semicolons and vice versa whenever there is otherwise a syntax error that makes the AST unparseable. I can add an exception, but it seems nice to keep this pattern so that it's easier for people to remember which delimiter to use.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry for missing this comment for some time... Yeah, it is a nice consistency argument. I was stealing the syntax from the record field separators, but I guess comma works as well. Will try and report back. @crusso any gut feelings about this?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd stick with ; since these are more like fields. Would be even nicer if they just were fields...

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, they are fields, but where is it written that they cannot be separated by commas? ;-) Just playing the devil's advocate.

Anyway, I have started a branch to get a feeling for the suggestion: #4782. I am not married to either way.

'if' <exp_nullary> <exp_nest>
'if' <exp_nullary> <exp_nest> 'else' <exp_nest>
'try' <exp_nest> <catch>
Expand Down
120 changes: 90 additions & 30 deletions src/codegen/compile_classical.ml
Original file line number Diff line number Diff line change
Expand Up @@ -2021,7 +2021,7 @@ module Tagged = struct
| T (* (T,+) *)
| S (* shared ... -> ... *)
type blob_sort =
| B (* Blob *)
| B (* Blob *)
| T (* Text *)
| P (* Principal *)
| A (* actor { ... } *)
Expand Down Expand Up @@ -2250,6 +2250,15 @@ module Tagged = struct
set_tag ^^
go cases

(* like branch_default_with but the tag is known statically *)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These changes need to be transported to %_enhanced.ml.

let branch_with env retty = function
| [] -> G.i Unreachable
| [_, code] -> code
| (_, code) :: cases ->
let (set_o, get_o) = new_local env "o" in
let prep (t, code) = (t, get_o ^^ code)
in set_o ^^ get_o ^^ branch_default env retty (get_o ^^ code) (List.map prep cases)

let allocation_barrier env =
(if !Flags.gc_strategy = Flags.Incremental then
E.call_import env "rts" "allocation_barrier"
Expand Down Expand Up @@ -2411,12 +2420,13 @@ module Opt = struct
( get_x ) (* true literal, no wrapping *)
( get_x ^^ Tagged.branch_default env [I32Type]
( get_x ) (* default tag, no wrapping *)
[ Tagged.Null,
Tagged.
[ Null,
(* NB: even ?null does not require allocation: We use a static
singleton for that: *)
compile_unboxed_const (vanilla_lit env (null_vanilla_lit env))
; Tagged.Some,
Tagged.obj env Tagged.Some [get_x]
; Some,
obj env Some [get_x]
]
)
)
Expand Down Expand Up @@ -2540,7 +2550,7 @@ module Closure = struct
I32Type :: Lib.List.make n_args I32Type,
FakeMultiVal.ty (Lib.List.make n_res I32Type))) in
(* get the table index *)
Tagged.load_forwarding_pointer env ^^
(*Tagged.load_forwarding_pointer env ^^ FIXME: NOT needed, accessing immut slots*)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are you sure this is ok? I'd first verify with @luc. Also, not related to this PR at all.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

have this in a separate PR?

Tagged.load_field env (funptr_field env) ^^
(* All done: Call! *)
let table_index = 0l in
Expand Down Expand Up @@ -5056,6 +5066,7 @@ module IC = struct
E.add_func_import env "ic0" "accept_message" [] [];
E.add_func_import env "ic0" "call_data_append" (i32s 2) [];
E.add_func_import env "ic0" "call_cycles_add128" (i64s 2) [];
E.add_func_import env "ic0" "call_with_best_effort_response" [I32Type] [];
E.add_func_import env "ic0" "call_new" (i32s 8) [];
E.add_func_import env "ic0" "call_perform" [] [I32Type];
E.add_func_import env "ic0" "call_on_cleanup" (i32s 2) [];
Expand Down Expand Up @@ -5508,7 +5519,7 @@ module IC = struct
| Flags.(ICMode | RefMode) ->
system_call env "call_cycles_add128"
| _ ->
E.trap_with env "cannot accept cycles when running locally"
E.trap_with env "cannot add cycles when running locally"
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

break this out?


let cycles_accept env =
match E.mode env with
Expand Down Expand Up @@ -9393,16 +9404,21 @@ end (* Var *)
that requires top-level cps conversion;
use new prims instead *)
module Internals = struct
let call_prelude_function env ae var =
let call_prelude_function_with_args env ae var args =
match VarEnv.lookup_var ae var with
| Some (VarEnv.Const (_, Const.Fun (mk_fi, _))) ->
compile_unboxed_zero ^^ (* A dummy closure *)
args ^^
G.i (Call (nr (mk_fi ())))
| _ -> assert false

let call_prelude_function env ae var =
call_prelude_function_with_args env ae var G.nop

let add_cycles env ae = call_prelude_function env ae "@add_cycles"
let reset_cycles env ae = call_prelude_function env ae "@reset_cycles"
let reset_refund env ae = call_prelude_function env ae "@reset_refund"
let pass_cycles env ae = call_prelude_function_with_args env ae "@pass_cycles"
end

(* This comes late because it also deals with messages *)
Expand Down Expand Up @@ -10870,7 +10886,7 @@ and compile_prim_invocation (env : E.t) ae p es at =

begin match p, es with
(* Calls *)
| CallPrim _, [e1; e2] ->
| CallPrim (_, par), [e1; e2] ->
let sort, control, _, arg_tys, ret_tys = Type.(as_func (promote e1.note.Note.typ)) in
let n_args = List.length arg_tys in
let return_arity = match control with
Expand All @@ -10884,8 +10900,7 @@ and compile_prim_invocation (env : E.t) ae p es at =
let call_as_prim = match fun_sr, sort with
| SR.Const (_, Const.Fun (mk_fi, Const.PrimWrapper prim)), _ ->
begin match n_args, e2.it with
| 0, _ -> true
| 1, _ -> true
| (0 | 1), _ -> true
| n, PrimE (TupPrim, es) when List.length es = n -> true
| _, _ -> false
end
Expand Down Expand Up @@ -10916,18 +10931,23 @@ and compile_prim_invocation (env : E.t) ae p es at =
StackRep.of_arity return_arity,

code1 ^^
compile_unboxed_zero ^^ (* A dummy closure *)
Type.(match as_obj par.note.Note.typ with
| Object, [] -> compile_unboxed_zero (* a dummy closure *)
| _ -> compile_exp_vanilla env ae par) ^^ (* parenthetical *)
compile_exp_as env ae (StackRep.of_arity n_args) e2 ^^ (* the args *)
G.i (Call (nr (mk_fi ()))) ^^
FakeMultiVal.load env (Lib.List.make return_arity I32Type)
| _, Type.Local ->
let (set_clos, get_clos) = new_local env "clos" in
let set_clos, get_clos = new_local env "clos" in

StackRep.of_arity return_arity,
code1 ^^ StackRep.adjust env fun_sr SR.Vanilla ^^
Closure.prepare_closure_call env ^^ (* FIXME: move to front elsewhere too *)
set_clos ^^
get_clos ^^
Closure.prepare_closure_call env ^^
Type.(match as_obj par.note.Note.typ, ret_tys with
| (Object, []), _ -> get_clos (* just the closure *)
| _, [ret] when is_async_fut ret -> Arr.lit env Tagged.T [compile_exp_vanilla env ae par; get_clos] (* parenthetical: pass a pair *)
| _ -> get_clos) ^^ (* just the closure *)
compile_exp_as env ae (StackRep.of_arity n_args) e2 ^^
get_clos ^^
Closure.call_closure env n_args return_arity
Expand All @@ -10938,8 +10958,10 @@ and compile_prim_invocation (env : E.t) ae p es at =
let (set_meth_pair, get_meth_pair) = new_local env "meth_pair" in
let (set_arg, get_arg) = new_local env "arg" in
let _, _, _, ts, _ = Type.as_func e1.note.Note.typ in
let add_cycles = Internals.add_cycles env ae in

let add_cycles = Type.(match as_obj par.note.Note.typ with
| Object, [] -> Internals.add_cycles env ae (* legacy *)
| _ -> compile_exp_vanilla env ae par ^^ Object.load_idx env par.note.Note.typ "cycles" ^^ Cycles.add env) (* parenthetical *)
in
StackRep.of_arity return_arity,
code1 ^^ StackRep.adjust env fun_sr SR.Vanilla ^^
set_meth_pair ^^
Expand Down Expand Up @@ -12112,24 +12134,27 @@ and compile_prim_invocation (env : E.t) ae p es at =
| ICCallerPrim, [] ->
SR.Vanilla, IC.caller env

| ICCallPrim, [f;e;k;r;c] ->
| ICCallPrim setup, [f;e;k;r;c] ->
SR.unit, begin
(* TBR: Can we do better than using the notes? *)
let _, _, _, ts1, _ = Type.as_func f.note.Note.typ in
let _, _, _, ts2, _ = Type.as_func k.note.Note.typ in
let (set_meth_pair, get_meth_pair) = new_local env "meth_pair" in
let (set_arg, get_arg) = new_local env "arg" in
let (set_k, get_k) = new_local env "k" in
let (set_r, get_r) = new_local env "r" in
let (set_c, get_c) = new_local env "c" in
let add_cycles = Internals.add_cycles env ae in
let set_meth_pair, get_meth_pair = new_local env "meth_pair" in
let set_arg, get_arg = new_local env "arg" in
let set_k, get_k = new_local env "k" in
let set_r, get_r = new_local env "r" in
let set_c, get_c = new_local env "c" in
let add_cycles = match setup with
| None -> Internals.add_cycles env ae
| Some exp -> compile_exp_vanilla env ae exp ^^ G.i Drop in
compile_exp_vanilla env ae f ^^ set_meth_pair ^^
compile_exp_vanilla env ae e ^^ set_arg ^^
compile_exp_vanilla env ae k ^^ set_k ^^
compile_exp_vanilla env ae r ^^ set_r ^^
compile_exp_vanilla env ae c ^^ set_c ^^
FuncDec.ic_call env ts1 ts2 get_meth_pair get_arg get_k get_r get_c add_cycles
end

| ICCallRawPrim, [p;m;a;k;r;c] ->
SR.unit, begin
let set_meth_pair, get_meth_pair = new_local env "meth_pair" in
Expand Down Expand Up @@ -12187,6 +12212,29 @@ and compile_prim_invocation (env : E.t) ae p es at =
SR.Vanilla, Cycles.refunded env
| SystemCyclesBurnPrim, [e1] ->
SR.Vanilla, compile_exp_vanilla env ae e1 ^^ Cycles.burn env
| ICCyclesPrim, [] ->
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not an idempotent operation, so we have to be careful to not call it twice. E.g. it fails for paired up environment+parenthetical.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should return two options. Possibly just the Nat (cycles) and Nat32 (timeout). We definitely have to search the attributes.

SR.Vanilla,
G.i (LocalGet (nr 0l)) ^^ (* closed-over bindings *)
G.if1 I32Type
begin
G.i (LocalGet (nr 0l)) ^^
Tagged.branch_with env [I32Type]
[ Tagged.Closure,
G.i Drop ^^
Opt.null_lit env
Copy link
Contributor Author

@ggreif ggreif Dec 11, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use br 1 to fall out?

; Tagged.(Array T),
Opt.inject_simple env (Arr.load_field env 0l) ^^
G.i (LocalGet (nr 0l)) ^^
Arr.load_field env 1l ^^
G.i (LocalSet (nr 0l))
; Tagged.Object,
Opt.inject_simple env G.nop
Copy link
Contributor Author

@ggreif ggreif Dec 11, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't care storing back anything, as there is no captured environment.

]
end
(Opt.null_lit env)

| SystemTimeoutPrim, [e1] ->
SR.unit, compile_exp_as env ae (SR.UnboxedWord32 Type.Nat32) e1 ^^ IC.system_call env "call_with_best_effort_response"

| SetCertifiedData, [e1] ->
SR.unit, compile_exp_vanilla env ae e1 ^^ IC.set_certified_data env
Expand Down Expand Up @@ -12360,15 +12408,27 @@ and compile_exp_with_hint (env : E.t) ae sr_hint exp =
let return_arity = List.length return_tys in
let mk_body env1 ae1 = compile_exp_as env1 ae1 (StackRep.of_arity return_arity) e in
FuncDec.lit env ae x sort control captured args mk_body return_tys exp.at
| SelfCallE (ts, exp_f, exp_k, exp_r, exp_c) ->
| SelfCallE (par, ts, exp_f, exp_k, exp_r, exp_c) ->
SR.unit,
let (set_future, get_future) = new_local env "future" in
let (set_k, get_k) = new_local env "k" in
let (set_r, get_r) = new_local env "r" in
let (set_c, get_c) = new_local env "c" in
let set_future, get_future = new_local env "future" in
let set_k, get_k = new_local env "k" in
let set_r, get_r = new_local env "r" in
let set_c, get_c = new_local env "c" in
let mk_body env1 ae1 = compile_exp_as env1 ae1 SR.unit exp_f in
let captured = Freevars.captured exp_f in
let add_cycles = Internals.add_cycles env ae in
let add_cycles = match par.it with
| LitE NullLit -> Internals.add_cycles env ae (* legacy *)
| _ when Type.(sub par.note.Note.typ (Opt (Obj (Object, [{ lab = "cycles"; typ = nat; src = empty_src}])))) ->
Internals.pass_cycles env ae (compile_exp_vanilla env ae par (*FIXME: effects?!*))
| _ -> Internals.pass_cycles env ae (Opt.null_lit env) in
let add_timeout = match par.note.Note.typ with
| (Type.Opt typ) when Type.(sub typ (Obj (Object, [{ lab = "timeout"; typ = nat32; src = empty_src}]))) ->
compile_exp_vanilla env ae par (*FIXME: effects?!*) ^^
(* this is a naked option, and no need to check is_some *)
Object.load_idx env typ "timeout" ^^
BitTagged.untag_i32 __LINE__ env Type.Nat32 ^^
IC.system_call env "call_with_best_effort_response"
| _ -> G.nop in
FuncDec.async_body env ae ts captured mk_body exp.at ^^
Tagged.load_forwarding_pointer env ^^
set_future ^^
Expand All @@ -12384,7 +12444,7 @@ and compile_exp_with_hint (env : E.t) ae sr_hint exp =
get_k
get_r
get_c
add_cycles
(add_cycles ^^ add_timeout)
| ActorE (ds, fs, _, _) ->
fatal "Local actors not supported by backend"
| NewObjE (Type.(Object | Module | Memory) as _sort, fs, _) ->
Expand Down
4 changes: 2 additions & 2 deletions src/codegen/compile_enhanced.ml
Original file line number Diff line number Diff line change
Expand Up @@ -12207,7 +12207,7 @@ and compile_prim_invocation (env : E.t) ae p es at =
| ICCallerPrim, [] ->
SR.Vanilla, IC.caller env

| ICCallPrim, [f;e;k;r;c] ->
| ICCallPrim _FIXME, [f;e;k;r;c] ->
SR.unit, begin
(* TBR: Can we do better than using the notes? *)
let _, _, _, ts1, _ = Type.as_func f.note.Note.typ in
Expand Down Expand Up @@ -12443,7 +12443,7 @@ and compile_exp_with_hint (env : E.t) ae sr_hint exp =
let return_arity = List.length return_tys in
let mk_body env1 ae1 = compile_exp_as env1 ae1 (StackRep.of_arity return_arity) e in
FuncDec.lit env ae x sort control captured args mk_body return_tys exp.at
| SelfCallE (ts, exp_f, exp_k, exp_r, exp_c) ->
| SelfCallE (cyc_FIXME, ts, exp_f, exp_k, exp_r, exp_c) ->
SR.unit,
let (set_future, get_future) = new_local env "future" in
let (set_k, get_k) = new_local env "k" in
Expand Down
27 changes: 18 additions & 9 deletions src/ir_def/arrange_ir.ml
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,15 @@ let rec exp e = match e.it with
| SwitchE (e, cs) -> "SwitchE" $$ [exp e] @ List.map case cs
| LoopE e1 -> "LoopE" $$ [exp e1]
| LabelE (i, t, e) -> "LabelE" $$ [id i; typ t; exp e]
| AsyncE (Type.Fut, tb, e, t) -> "AsyncE" $$ [typ_bind tb; exp e; typ t]
| AsyncE (Type.Cmp, tb, e, t) -> "AsyncE*" $$ [typ_bind tb; exp e; typ t]
| AsyncE (None, Type.Fut, tb, e, t) -> "AsyncE" $$ [typ_bind tb; exp e; typ t]
| AsyncE (Some par, Type.Fut, tb, e, t) -> "AsyncE()" $$ [exp par; typ_bind tb; exp e; typ t]
| AsyncE (_, Type.Cmp, tb, e, t) -> "AsyncE*" $$ [typ_bind tb; exp e; typ t]
| DeclareE (i, t, e1) -> "DeclareE" $$ [id i; exp e1]
| DefineE (i, m, e1) -> "DefineE" $$ [id i; mut m; exp e1]
| FuncE (x, s, c, tp, as_, ts, e) ->
"FuncE" $$ [Atom x; func_sort s; control c] @ List.map typ_bind tp @ args as_ @ [ typ (Type.seq ts); exp e]
| SelfCallE (ts, exp_f, exp_k, exp_r, exp_c) ->
"SelfCallE" $$ [typ (Type.seq ts); exp exp_f; exp exp_k; exp exp_r; exp exp_c]
| SelfCallE (_FIXME, ts, exp_f, exp_k, exp_r, exp_c) ->
"SelfCallE" $$ [exp _FIXME; typ (Type.seq ts); exp exp_f; exp exp_k; exp exp_r; exp exp_c]
| ActorE (ds, fs, u, t) -> "ActorE" $$ List.map dec ds @ fields fs @ [system u; typ t]
| NewObjE (s, fs, t) -> "NewObjE" $$ (Arrange_type.obj_sort s :: fields fs @ [typ t])
| TryE (e, cs, None) -> "TryE" $$ [exp e] @ List.map case cs
Expand Down Expand Up @@ -60,7 +61,8 @@ and args = function
and arg a = Atom a.it

and prim = function
| CallPrim ts -> "CallPrim" $$ List.map typ ts
| CallPrim (ts, par) when empty par -> "CallPrim" $$ List.map typ ts
| CallPrim (ts, par) -> "CallPrim()" $$ [exp par] @ List.map typ ts
| UnPrim (t, uo) -> "UnPrim" $$ [typ t; Arrange_ops.unop uo]
| BinPrim (t, bo) -> "BinPrim" $$ [typ t; Arrange_ops.binop bo]
| RelPrim (t, ro) -> "RelPrim" $$ [typ t; Arrange_ops.relop ro]
Expand Down Expand Up @@ -94,34 +96,41 @@ and prim = function
| ActorOfIdBlob t -> "ActorOfIdBlob" $$ [typ t]
| BlobOfIcUrl -> Atom "BlobOfIcUrl"
| IcUrlOfBlob -> Atom "IcUrlOfBlob"
| SelfRef t -> "SelfRef" $$ [typ t]
| SelfRef t -> "SelfRef" $$ [typ t]
| SystemTimePrim -> Atom "SystemTimePrim"
| SystemTimeoutPrim -> Atom "SystemTimeoutPrim"
| SystemCyclesAddPrim -> Atom "SystemCyclesAddPrim"
| SystemCyclesAcceptPrim -> Atom "SystemCyclesAcceptPrim"
| SystemCyclesAvailablePrim -> Atom "SystemCyclesAvailablePrim"
| SystemCyclesBalancePrim -> Atom "SystemCyclesBalancePrim"
| SystemCyclesRefundedPrim -> Atom "SystemCyclesRefundedPrim"
| SystemCyclesBurnPrim -> Atom "SystemCyclesBurnPrim"
| ICCyclesPrim -> Atom "ICCyclesPrim"
| SetCertifiedData -> Atom "SetCertifiedData"
| GetCertificate -> Atom "GetCertificate"
| OtherPrim s -> Atom s
| CPSAwait (Type.Fut, t) -> "CPSAwait" $$ [typ t]
| CPSAwait (Type.Cmp, t) -> "CPSAwait*" $$ [typ t]
| CPSAsync (Type.Fut, t) -> "CPSAsync" $$ [typ t]
| CPSAsync (Type.Cmp, t) -> "CPSAsync*" $$ [typ t]
| CPSAsync (Type.Fut, t, par) -> "CPSAsync" $$ [exp par] @ [typ t]
| CPSAsync (Type.Cmp, t, _) -> "CPSAsync*" $$ [typ t]
| ICArgDataPrim -> Atom "ICArgDataPrim"
| ICStableSize t -> "ICStableSize" $$ [typ t]
| ICPerformGC -> Atom "ICPerformGC"
| ICReplyPrim ts -> "ICReplyPrim" $$ List.map typ ts
| ICRejectPrim -> Atom "ICRejectPrim"
| ICCallerPrim -> Atom "ICCallerPrim"
| ICCallPrim -> Atom "ICCallPrim"
| ICCallPrim e -> "ICCallPrim" $$ Option.(map exp e |> to_list)
| ICCallRawPrim -> Atom "ICCallRawPrim"
| ICMethodNamePrim -> Atom "ICMethodNamePrim"
| ICReplyDeadlinePrim -> Atom "ICReplyDeadlinePrim"
| ICStableWrite t -> "ICStableWrite" $$ [typ t]
| ICStableRead t -> "ICStableRead" $$ [typ t]

and empty exp =
Type.(is_obj exp.note.Note.typ
&& (let (s, fls) = as_obj exp.note.Note.typ in
s = Object && fls = []))

and mut = function
| Const -> Atom "Const"
| Var -> Atom "Var"
Expand Down
Loading
Loading