Skip to content
This repository was archived by the owner on Nov 3, 2021. It is now read-only.
This repository was archived by the owner on Nov 3, 2021. It is now read-only.

Typed select's return type representation #64

Closed

Description

@aheejin

This proposal introduces a typed select instruction, which takes reference types and also a return type. The return type is written as a vector of valtype. Currently only the vector of length 1 is accepted in the v8 validation. I guess the reason it is a vector is for the multivalue proposal, right?

Is there a reason this has a different representation from that of block, loop, and if type when there are multiple types? blocktype for the multivalue proposal says it is extended to have a type index in the presence of multi values. This will be applied to other instructions such as loops and ifs. Wouldn't it be better for select to be consistent?

cc @tlively

Activity

  1. rossberg commented on Nov 20, 2019

    @rossberg
    Member

    See this comment for the rationale behind the format. I honestly don't know what a block type (as introduced by multi-values) would mean for select, since the instruction does not have independent argument and result types, like blocks have.

  2. tlively commented on Nov 20, 2019

    @tlively
    Member

    Could we enforce in validation that the input types be empty and the output types be whatever would be in the vector today? Or maybe inputs and outputs should be the same. Or maybe the signature should be the full type of the select, including the condition.

    Anyway, we can enforce whatever signatures make the most sense. The rationale for doing this is the same as the rationale for disallowing inline multivalue block types, that is deduplication of types and compactness of encoding.

  3. rossberg commented on Nov 21, 2019

    @rossberg
    Member

    We could, but it would be odd -- for example, then we'd need to artificially introduce the params into the text format, too.

    In terms of compactness it wouldn't actually be a win here: most of the cases where it would be a win (single argument) are covered with even less bytes by the existing unannotated select already. And for multi-parameter cases, going through a func type can easily be a net loss rather than a win if it is a one-off use.

    And of course, compactness isn't even remotely as relevant for this instruction as it is for blocks, since its frequency of use will almost certainly be in the noise.

    (FWIW, I believe we discussed and concluded all this at the A Coruna meeting.)

  4. tlively commented on Nov 21, 2019

    @tlively
    Member

    Ok, it sounds like there are good reasons for this and I don’t want to needlessly rehash old discussions. Thanks for your explanations!

  5. tlively commented on Nov 22, 2019

    @tlively
    Member

    @rossberg I just realized there is another place where we constrain signature types. In the exceptions proposal the event signatures must have empty result types: https://github.com/WebAssembly/exception-handling/blob/master/proposals/Exceptions.md#event-handling. Does that make enforcing a similar constraint for select sufficiently less odd that we should reconsider it?

  6. rossberg commented on Nov 23, 2019

    @rossberg
    Member

    Ah, that's a somewhat different story. For events, non-empty result types are reserved and will actually be meaningful with future extensions for resumable exceptions / effect handlers / coroutines / stack switching (I plan to present more concrete ideas at the Feb meeting). So that's more like the situation with block signatures.

  7. bitwalker commented on Nov 23, 2019

    @bitwalker

    @rossberg Do you have any notes or anything about what you have in mind for coroutines/stack switching? I'm most interested in whether or not the coroutine primitives would be designed around stackful coroutines, or stackless coroutines. Presumably the presence of stack switching primitives would allow for the former, so I guess even if the coroutine primitives are stackless, having the stack switching primitives would be enough to do what I need.

    If you recall we had some discussion on an issue earlier this year about coroutines/continuations, but there was no immediate plans to support anything like that, other than the possibility that resumable exceptions might provide a way to implement a form of delimited continuations; and the lack of appropriate stack primitives meant neither coroutines nor continuations could be implemented from the ground up either. If that is something that will change in the the coming year, that would be fantastic! I definitely would be interested in helping move that work forward, if I can be of assistance.

  8. rossberg commented on Nov 24, 2019

    @rossberg
    Member

    @bitwalker, nothing I can currently point to, sorry. But yes, the goal here is to provide a "stack switching" primitive, so in C++ terminology, it would be "stackful" coroutines. AFAICS, "stackless" pseudo coroutines aren't all that interesting for Wasm, since a producer can implement them themselves via a fairly local program transformation.

    The more interesting distinction is between symmetric and asymmetric coroutines, and this would be the latter.

    Roughly, the idea is a new reference type cont $ft of continuations (a.k.a. stacks), where $ft is a function type, along with respective instructions cont.new, cont.yield, cont.resume, and a few more. Unlike more conventional coroutines, the continuation type allows passing values back and forth between yield and resume points. But this has to be typed properly in Wasm, and that's where event declarations come in: yield generates an event with a certain type and passes along its arguments (like throw). It can only be resumed by passing back the event's results (adopting ideas from effect handlers). Like exceptions and their exn values, events are captured as first-class values of a type evt, so that resumption can happen even after the parent has returned.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions