Skip to content
This repository was archived by the owner on Apr 25, 2025. It is now read-only.
This repository was archived by the owner on Apr 25, 2025. It is now read-only.

Match delegate's immediate and label argument to those of branches #146

Closed
@aheejin

Description

@aheejin

I'd like to suggest a slight change to the current seemingly discussed spec in #143 so that we can treat the target of brs and delegates in a similar way in the wast format. I think this will help reading and writing the wast format and spec tests.

I'm not actually very sure if this will be a suggestion to change, because after discussions w/ @thibaudmichaud I realized my understanding was different from his and what I'd like to suggest here was actually already more in line with his V8
implementation. (Now I think we two are on the same page.)

So what I'd like to achieve is we can write the argument of delegate as labels in the wast format, as we do for br/br_ifs, and make delegate can syntactically target a try, which semantically in turn goes to that try's corresponding catch. delegate's immediate argument is translated to the labels in the same way we do for brs. Let me illustrate that with an example. I annotated catches with their corresponding try's labels just to make it more readable. The example looks a bit long, but please bear with me:

try $labelA
catch ($labelA)
  block $labelB
    try $labelC
      br 0         (= br $labelC)
      br 1         (= br $labelB)
      br 2         (= br $labelA)
      try
      delegate 0   (= delegate $labelC, which delegates to 'catch ($labelC)')
      try
      delegate 1   (= delegate $labelB, which is a block, so validation failure)
      try
      delegate 2   (= delegate $labelA, which delegates to 'catch ($labelA)', but 'catch ($labelA)' is above this instruction, so validation failure)
      try
      delegate 3   (= delegate to the caller)
    catch ($labelC)
      br 0         (= br $labelC)
      br 1         (= br $labelB)
      br 2         (= br $labelA)
      try
      delegate 0   (= delegate $labelC, which delegates to 'catch ($labelC)', but 'catch ($labelC)' is above this instruction, so validation failure)
      try
      delegate 1   (= delegate $labelB, which is a block, so validation failure)
      try
      delegate 2   (= delegate $labelA, which delegates to 'catch ($labelA)', but 'catch ($labelA)' is above this instruction, so validation failure)
      try
      delegate 3   (= delegate to the caller)
    end  ;; try $labelC
  end ;; block $labelB
end ;; try $labelA

(catches can be either catch or catch_all, it doesn't really matter here. unwind will be treated the same.)

So what I propose is basically this: Treat delegate's immediate/label in the same way as br's immediate/label. delegate also can target any of block/loop/try, but if the target is a block or loop it is a validation failure. (I think this was discussed somewhat already in #143).

If the target is a try, if the try's corresponding catch is below the delegate as in the first delegate 0 in my example, it delegates to that catch. If the corresponding catch is above the delegate as in the second delegate 0 in my example, we can't delegate to somewhere upwards, so it is a validation failure. Please notice the difference between two delegate 0's interpretation in my example. But the advantage of this format is we can maintain a single control flow stack, and use labels and immediates interchangeably in the wast format as we already do for br/br_if. In my example brs are just written to show that when br's immediate and delegate's immediate are the same, their label arguments will also be the same.

Also, when there are multiple catch/catch_alls per try, they are treated as a chunk. So

try $labelA
catch tag_a ($labelA)
  try
  delegate 0  ;; validation failure
catch tag_b
  ...
catch_all
  ...
end

delegate 0 here targets $labelA's all catches as a chunk. Because catch tag_a is above this delegate 0, this is rather a validation failure, and it does not delegate to catch tag_b or catch_all below.

I'm not necessarily trying to discuss the formal spec yet; if we are all on the same page on the operational semantics in informal English, I think we can proceed to the format version.

WDYT? cc @thibaudmichaud @backes @ioannad @takikawa @tlively

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