-
Notifications
You must be signed in to change notification settings - Fork 458
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
Branch-like structured control flow #98
Conversation
Not needing to explicitly label all loops/switches is a big improvement, so I'm in favor of that. Not super thrilled by I'll do a detailed review of this PR later... |
Does 'syntax sugar' mean operations that are only implement in the syntax, and that there would not be binary opcode for them? This would seem fine to me as the consumer needs to recognize either pattern anyway and having a canonical representation might even make it easier. |
I take issues with that choice. You are trading 3 core primitives for 5, |
@JSStats, sugar means it is part of the language, but defined
(straightforwardly) in terms of simpler primitives. This doesn't
affect users, it only is a means of simplifying the spec.
|
The most interesting example though is |
3b255d9
to
c7ed6fb
Compare
| "br_if" { BRIF } | ||
| "br_unless" { BRUNLESS } | ||
| "if" { IF } | ||
| "else" { ELSE } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this ELSE token used?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nope. Good spot.
Why keep both Why keep both If we have both a |
951761a
to
68cab87
Compare
In this PR,
Recently there's been discussion of using dense arrays of case values rather than sparse, and requiring the array to start at zero, which I'm tentatively thinking make sense for |
FWIW, in v8-native prototype I implemented a couple variants of switch, one with default fallthrough and one without. It's only a couple lines of code difference between the two. A general switch with labels and default (especially in the middle) is more work, and without some examples of typical switch constructs in programs, it's tough to tell what the right tradeoff is yet, since I think fallthrough in general switches will result in some ugly if-cascades. |
I'm not a huge fan of this new syntax. Having labels defined after use is not great (though I suppose we already do that for functions). Using label indexes seem non-intuitive now too. Previously the label index corresponded to break depth, counting up from zero. How does it work now? Also seems weird to have loop require an explicit branch. This means you can fall off the end of a loop or branch backward to an outer loop, right? It seems that the only difference between loop and block is the location of the label? The syntax also seems to encourage a somewhat bizarre layout scheme where the blocks are flattened and the labels are dedented. This is very apparent in the block cascade of the br_switch statement. |
Label indices in this proposal work in the same way as they do in the current ml-proto code, corresponding to break depth in exactly the same way. You can use a name in place of a label in the current ml-proto code too. Block labels at the bottom is something that looks natural to me, because that's where the code goes when it branches to that label. I find JS labeled blocks awkward because I have to find the label at the top and them jump down to the bottom to see where the code is going. But if people prefer to declare the labels at the top, it's easy to implement. Yes, the only difference between block and loop in this proposal is the location of the label. Requiring an explicit branch to stay in the loop is very natural from a compiler perspective. If it would help people understand what's going on here, I'd be ok renaming 'loop' to something else. The big picture is that this proposal is inspired by compilers and low-level tools, where there is a desire for control transfers to be simple, unopinionated, and representable in a linear fashion (as this proposal is). It stops short of being a fully general CFG, because this lets us keep a hierarchical structure and the various nice properties that entails, but it's very easy to emit from a compiler with a CFG. |
68cab87
to
19e2c08
Compare
I'm not pursuing this PR presently, so closing. |
And remove i8x16.mul, as documented in WebAssembly#28 and WebAssembly#98.
- Removed unnecessary/mismatching lookup of table/memory type in execution prose - Added missing result type lookup in formal rule for table.size and memory.size - Fixed computation of -1 result value for table.grow and table.size to work for i64 - Some fixes around specification of text format for inline elements/data shorthand - Fixed matching rules for tabletype/memtype to enforce same address type Split out from #1839
* Fix validation of `switch`. The validation of `switch` was not working as intended when the "switcher" and "switchee" had different continuation type immediates. The fix is to replace the current continuation from the argument list with the switched-to continuation. The previous thing happened to be working when the "switcher" and "switchee" used the same continuation type immediate. I also noticed a bug in the testsuite runner. It was not running the stack switching tests since commit WebAssembly/stack-switching@70086b9. I have added the "stack-switching" subdirectory to the test script runner such that the tests are now being run again by `make test`. Resolves WebAssembly#98. * Update interpreter/valid/valid.ml Co-authored-by: Andreas Rossberg <rossberg@mpi-sws.org> --------- Co-authored-by: Andreas Rossberg <rossberg@mpi-sws.org>
This PR is initial work pursuant to the current discussion around WebAssembly/design#299, adding the new low-level operators suggested by the discussion while preserving the existing high-level operators.
I took @rossberg-chromium's suggestion to use syntax sugar to keep the core code simple, though I instead implemented
if
/else
/forever
/break
(forever
was previouslyloop
in the spec repo, but it'sforever
in the design repo) as syntax sugar in terms ofbr
/br_if
/br_unless
because it makes the core spec simpler.The one exception is
switch
, which is not yet implemented as syntax sugar, but only because I haven't gotten around to it, and wanted feedback first.I also took the liberty of adding a bit of extra sweetener to the syntax sugar for the high-level opcodes. One can now use
break
on aforever
loop orswitch
without wrapping it in an explicitlabel
/block
, which more closely resembles the languages this syntax sugar is inspired by.