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

exploration: finally #4507

Draft
wants to merge 57 commits into
base: master
Choose a base branch
from
Draft

exploration: finally #4507

wants to merge 57 commits into from

Conversation

ggreif
Copy link
Contributor

@ggreif ggreif commented Apr 22, 2024

Let's figure out how to interpret finally first...

TODO:

  • handle Throw and regular continuations in await.ml (instead of desugaring)
    • adjust IR interpreter
  • how are label continuations invoked in the backend? (I need to know for the last-resort callback)
    • have a new context key sort Cleanup, stack up continuations of finally blocks only
    • extend the kr in await.ml to krc (CPSAwait), pass Cleanup continuations as c
    • add new primitive to compiler to set the last-resort field
    • in async.ml lower CPSAwait to that too
    • adapt check_ir.ml, etc.
  • fix up the syntax part
  • do ... finally (when there is no catch clause necessary)
  • type checking for the finally clause
    • unit result
    • trivial effect
  • other type than unit for try
  • OtherPrim "call_raw" + tests
  • cps_asyncE similarly to CallPrim/3

@ggreif ggreif added feature New feature or request language design Requires design work interpreter DO-NOT-MERGE labels Apr 22, 2024
let k' = fun v1 -> interpret_catches env cases exp.at v1 k in
let env' = { env with throws = Some k' } in
interpret_exp env' exp1 k
| TryE (exp1, cases, Some exp2) ->
let k' v1 =
let cleanup v2 = interpret_exp env exp2 (fun _ -> k v2) in
Copy link
Contributor Author

Choose a reason for hiding this comment

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

instead of ignoring what comes out of exp2's evaluation, explicitly check that it is unit: use V.as_unit

let cleanup v2 = interpret_exp env exp2 (fun _ -> k v2) in
interpret_catches env cases exp.at v1 cleanup in
let env' = { env with throws = Some k' } in
let k'' v2 = interpret_exp env' exp2 (fun _ -> k v2) in
Copy link
Contributor Author

Choose a reason for hiding this comment

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

here too!

Copy link

github-actions bot commented Apr 22, 2024

Comparing from 760676a to 8d649be:
The produced WebAssembly code seems to be completely unchanged.

let k' v1 =
let cleanup v2 = interpret_exp env exp2 (fun _ -> k v2) in
interpret_catches env cases exp.at v1 cleanup in
let env' = { env with throws = Some k' } in
Copy link
Contributor

@crusso crusso Apr 24, 2024

Choose a reason for hiding this comment

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

I'm not sure this is enough. Unless we disallow returns and breaks from exp1 and cases, I think you will need to redefine the rets and labs continuations too, to execute the finally before proceeding. This is getting complicated....

Copy link
Contributor

Choose a reason for hiding this comment

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

I think your current code will allow a return (or break) from exp1 or cases to skip the finally clause - only if the execution falls through exp1 or cases is the finally clause executed. A throw from cases will probably also bypass the finally.

Copy link
Contributor

Choose a reason for hiding this comment

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
DO-NOT-MERGE feature New feature or request interpreter language design Requires design work
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants