Skip to content

Conversation

dhil
Copy link
Member

@dhil dhil commented Sep 8, 2024

This patch implements a semantics for named handlers. It adds the following new types and instructions:

  • handler ts*
    • A new reference type for handler names.
  • resume_with $ct (on ...) : [ts1* (ref null $ct)] -> [ts2*]
    • where $ct ~~ func [ts1* (ref $handler)] -> [ts2*]
    • and $handler ~~ handler ts2*
    • Operationally, it works like resume, but with the small tweak that it generates and passes a unique name to the continuation.
  • suspend_to $handler $tag : [ts1* (ref null $handler)] -> [ts2*]
    • where $handler ~~ handler $ts3
    • and $tag ~~ func [ts1*] -> [ts2*]
    • It is similar to suspend, but rather than suspending to the nearest enclosing handler, it suspend to a particular given handler.

I've added a few tests too.

@dhil dhil force-pushed the wasmfx-named-handlers branch from f3c3bf5 to a08eebf Compare October 21, 2024 12:51
@dhil dhil mentioned this pull request Nov 4, 2024
3 tasks
@dhil dhil force-pushed the wasmfx-named-handlers branch from a08eebf to d9df8cd Compare December 3, 2024 13:48
@dhil dhil force-pushed the wasmfx-named-handlers branch from 53d6b96 to 946e356 Compare February 18, 2025 11:44
@@ -37,12 +38,14 @@ and struct_type = StructT of field_type list
and array_type = ArrayT of field_type
and func_type = FuncT of result_type * result_type
and cont_type = ContT of heap_type
and handler_type = HandlerT of result_type

Choose a reason for hiding this comment

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

I dont think that it is actually necessary to entangle the handler_type with the result type.
The reason is that you have to provide a tag when you use suspend_to. There does not seem to be any additional safety: suspend_to means to find the appropriate tag with the appropriate value of handler.

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes, you are correct. We can get away without result types on handler names.

One thing I'd like to experiment with is embedding the "types" of tags into the handler name type, that way, we would be able to statically ensure a given handler handles the suspension (if the handler exists). Then one can imagine suspend_to generating a static index into the handler's dispatch table.

Choose a reason for hiding this comment

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

I don't think that such a static index is possible. A given handle type may originate from different handler resume points. (In fact, that is pretty likely in my view.)

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes, I am not talking about the handler installation point / resume point / stack, but the index into the particular (on ...) dispatch table.

Choose a reason for hiding this comment

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

Umm. This is not computing for me. That is the resume point. Or rather, it is the suspension return point. Again, knowing the type of the handle will not permit this index to be statically known.

Copy link
Member Author

Choose a reason for hiding this comment

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

There are two things going on: 1) locate the handler (resume point); and 2) jump to the right branch inside the handler. It is the latter I am talking about.

Choose a reason for hiding this comment

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

Still don't see it.
OTOH, assuming that you model the handle value as an integer, you could split the integer: have the lower few bits encode that index. Since the handle is tied to a particular tag; and assuming that a given tag cannot occur multiple times in the handler table, then that will allow you jump to the right handler.

Copy link
Member Author

Choose a reason for hiding this comment

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

I don't understand what you mean by "the handle is tied to a particular tag". The assumption that a given tag cannot occur multiple times is false without some runtime processing/optimisation. In general, you cannot tell until module instantiation and linking whether any two tags are the same, because it is possible to import and export tags. Irrespectively, you don't know anything about the shape of the handler clause dispatch table when you suspend/suspend_to, so I don't see how your proposal would work.

If we could somehow talk about the types of tags, then we could embed them in the handler name type, which would then precisely describe the shape of the handler dispatch table (e.g. we could make it a validation error to have more or fewer (on ...) clauses than the handler name type). In essence, the handler name type would be a kind of variant type. The dispatch table can then be coded as a simple variant case-split elimination, which can be represented as a dense array mapping indexes to labels. The indexes can be computed statically by looking at the type of the handler name.

Choose a reason for hiding this comment

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

We seem to be misunderstanding each other.

  1. I am assuming that a given handler table (associated with a resume_with) may be the target of both suspend & suspend_to instructions.
  2. Even if a coroutine is resumed using resume_with, it may use either (or both at different times) a suspend and suspend_to to suspend itself.
  3. A given tag may be used in a resume handler table and a resume_with handler table
  4. A given tag may be used in different 'shapes' of handler tables. This is important as it allows coalescing of use cases (combining (for example) green thread-style yields with message channel stuffing).

What this means, I believe, is that there is no obvious ADT that models definitively the reasons for suspending. (You can force it, which is what I was doing in bag o stacks design.)

I.e. the pair handle/tag cant necessarily provide an index into all possible handler tables.

Perhaps, my assumptions are not matching yours?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants