summaryrefslogtreecommitdiff
path: root/src/passes/Print.cpp
Commit message (Collapse)AuthorAgeFilesLines
* Print castType for unreachable br_on_cast{_fail} (#7107)Thomas Lively2024-11-221-6/+4
| | | | | | | | I forgot that there is a validation rule that the output type for br_on_cast and br_on_cast_fail must be a subtype of the input type. We were previously printing bottom input types in cases where the cast operand was unreachable, but that's only valid if the cast type is the same bottom type. Instead print the most precise valid input type, which is the cast type itself.
* Print unreachable loads with valid types (#7108)Thomas Lively2024-11-221-1/+9
| | | | | | | | | Since Load expressions use their `type` field to encode the type of the loaded value, unreachable loads need to come up with some other valid type to print. Previously we always chose i32 as that type, but that's not valid when the load was originally a v128 load with an alignment of 8, since 8 is greater than the maximum valid alignment of 4 for an i32. Fix the problem by taking alignment into account when choosing a type for the unreachable load.
* Fix printing of unreachable br_on_cast{_fail} (#7102)Thomas Lively2024-11-211-2/+15
| | | | | | | | | | | | | br_on_cast and br_on_cast_fail have two type annotations: one for their input type and one for their cast type. In cases where their operands were unreachable, we were previously printing "unreachable" for the input type annotation. This is not valid wat because "unreachable" is not a reference type. To fix the problem, print the bottom type of the cast type's hierarchy as the input type for br_on_cast and br_on_cast_fail when the operand is unreachable. This ensures that the instructions have the most precise possible output type according to Wasm typing rules, so it maximizes the number of contexts in which the printed instructions are valid.
* Consolidate printing of function signatures (#7073)Thomas Lively2024-11-121-56/+43
| | | | | | | | | | | There were previously two separate code paths for printing function signatures, one for imported functions and one for declared functions. The only intended difference was that parameter names were printed for declared functions but not for imported functions. Reduce duplication by consolidating the code paths, and add support for printing names for imported function parameters that have them. Also fix a bug where empty names were printed as `$` rather than the correct `$""`.
* [NFC] Fix copy-paste error in TryTable printing (#7044)Alon Zakai2024-10-311-1/+1
|
* Source Maps: Support 5 segment mappings (#6795)Ömer Sinan Ağacan2024-10-011-1/+9
| | | | | | | Support 5-segment source mappings, which add a name. Reference: https://github.com/tc39/source-map/blob/main/source-map-rev3.md#proposed-format
* [NFC] Print type names in more places when logging (#6975)Alon Zakai2024-09-301-0/+5
|
* [FP16] Implement conversion operations. (#6974)Brendan Dahl2024-09-261-0/+12
| | | | | | | | | | Note: FP16 is a little different from F32/F64 since it can't represent the full 2^16 integer range. 65504 is the max whole integer. This leads to some slightly strange behavior when converting integers greater than 65504 since they become infinity. Specified at https://github.com/WebAssembly/half-precision/blob/main/proposals/half-precision/Overview.md
* [NFC] Eagerly create segments when parsing datacount (#6958)Thomas Lively2024-09-191-0/+5
| | | | | | | | | The purpose of the datacount section is to pre-declare how many data segments there will be so that engines can allocate space for them and not have to back patch subsequent instructions in the code section that refer to them. Once we use IRBuilder in the binary parser, we will have to have the data segments available by the time we parse instructions that use them, so eagerly construct the data segments when parsing the datacount section.
* [NFC] Eagerly create Functions in binary parser (#6957)Thomas Lively2024-09-191-0/+3
| | | | | | | | In preparation for using IRBuilder in the binary parser, eagerly create Functions when parsing the function section so that they are already created once we parse the code section. IRBuilder will require the functions to exist when parsing calls so it can figure out what type each call should have, even when there is a call to a function whose body has not been parsed yet.
* [FP16] Implement madd and nmadd. (#6878)Brendan Dahl2024-09-031-0/+6
| | | | | | | | | | | | | | Specified at https://github.com/WebAssembly/half-precision/blob/main/proposals/half-precision/Overview.md A few notes: - The F32x4 and F64x2 versions of madd and nmadd are missing spect tests. - For madd, the implementation was incorrectly doing `(b*c)+a` where it should be `(a*b)+c`. - For nmadd, the implementation was incorrectly doing `(-b*c)+a` where it should be `-(a*b)+c`. - There doesn't appear to be a great way to actually implement a fused nmadd, but the spec allows the double rounded version I added.
* Rename relaxed SIMD fma instructions to match spec. (#6876)Brendan Dahl2024-08-271-8/+8
| | | | | | | The instructions relaxed_fma and relaxed_fnma have been renamed to relaxed_madd and relaxed_nmadd. https://github.com/WebAssembly/relaxed-simd/blob/main/proposals/relaxed-simd/Overview.md#binary-format
* [FP16] Implement unary operations. (#6867)Brendan Dahl2024-08-271-0/+21
| | | | Specified at https://github.com/WebAssembly/half-precision/blob/main/proposals/half-precision/Overview.md
* [FP16] Implement arithmetic operations. (#6855)Brendan Dahl2024-08-211-0/+25
| | | | Specified at https://github.com/WebAssembly/half-precision/blob/main/proposals/half-precision/Overview.md
* Print explicit typeuses for non-MVP function types (#6851)Thomas Lively2024-08-191-2/+11
| | | | | | | | | We previously printed explicit typeuses (e.g. `(type $f)`) in function signatures when GC was enabled. But even when GC is not enabled, function types may use non-MVP features that require the explicit typeuse to be printed. Fix the printer to always print the explicit type use for such types. Fixes #6850.
* Implement table.init (#6827)Alon Zakai2024-08-161-0/+6
| | | | | Also use TableInit in the interpreter to initialize module's table state, which will now handle traps properly, fixing #6431
* Typed continuations: update syntax of handler clauses (#6824)Frank Emrich2024-08-091-3/+1
| | | | | | | | | | | | | | | | | | | | | The syntax for handler clauses in `resume` instructions has recently changed, using `on` instead of `tag` now. Instead of ``` (resume $ct (tag $tag0 $block0) ... (tag $tagn $blockn)) ``` we now have ``` (resume $ct (on $tag0 $block0) ... (on $tagn $blockn)) ``` This PR adapts parsing, printing, and some tests accordingly. (Note that this PR deliberately makes none of the other changes that will arise from implementing the new, combined stack switching proposal, yet.)
* [FP16] Implement relation operations. (#6825)Brendan Dahl2024-08-091-0/+18
| | | | Specified at https://github.com/WebAssembly/half-precision/blob/main/proposals/half-precision/Overview.md
* [FP16] Implement lane access instructions. (#6821)Brendan Dahl2024-08-081-0/+9
| | | | Specified at https://github.com/WebAssembly/half-precision/blob/main/proposals/half-precision/Overview.md
* [FP16] Implement load and store instructions. (#6796)Brendan Dahl2024-08-061-3/+13
| | | | Specified at https://github.com/WebAssembly/half-precision/blob/main/proposals/half-precision/Overview.md
* [threads] ref.i31_shared (#6735)Thomas Lively2024-07-121-1/+5
| | | | | | | Implement `ref.i31_shared` the new instruction for creating references to shared i31s. Implement binary and text parsing and emitting as well as interpretation. Copy the upstream spec test for i31 and modify it so that all the heap types are shared. Comment out some parts that we do not yet support.
* Do not abbreviate items in element segments (#6737)Thomas Lively2024-07-121-1/+2
| | | | | | | | The full syntax for an expression in an element syntax looks like `(item (ref.null none))`, but we have been printing the abbreviated version, which omits the `(item ...)`. This abbreviation is only valid when the item has only a single instruction, so it is not always correct to use it. Rather than determining whether or not to use the abbreviation on a case-by-case basis, always print the full syntax.
* Rename external conversion instructions (#6716)Jérôme Vouillon2024-07-081-4/+4
| | | | | | | | | Rename instructions `extern.internalize` into `any.convert_extern` and `extern.externalize` into `extern.convert_any` to follow more closely the spec. This was changed in https://github.com/WebAssembly/gc/issues/432. The legacy name is still accepted in text inputs and in the C and JS APIs.
* Add local.set/tee local type annotations to BINARYEN_PRINT_FULL (#6657)Alon Zakai2024-06-131-12/+25
| | | | | | | | | | | | | With this we now print e.g. (local.set $temp (; local type: i32 ;) ... This can be nice in large functions to avoid needing to scroll up to see the local type, e.g. when debugging why unsubtyping doesn't work somewhere. Also avoid [ ] in this mode, in favor of the standard (; ;), and put those at the end rather than at the start.
* [Strings] Remove operations not included in imported strings (#6589)Thomas Lively2024-05-151-53/+0
| | | | | | The stringref proposal has been superseded by the imported JS strings proposal, but the former has many more operations than the latter. To reduce complexity, remove all operations that are part of stringref but not part of imported strings.
* [Strings] Remove stringview types and instructions (#6579)Thomas Lively2024-05-151-49/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | The stringview types from the stringref proposal have three irregularities that break common invariants and require pervasive special casing to handle properly: they are supertypes of `none` but not subtypes of `any`, they cannot be the targets of casts, and they cannot be used to construct nullable references. At the same time, the stringref proposal has been superseded by the imported strings proposal, which does not have these irregularities. The cost of maintaing and improving our support for stringview types is no longer worth the benefit of supporting them. Simplify the code base by entirely removing the stringview types and related instructions that do not have analogues in the imported strings proposal and do not make sense in the absense of stringviews. Three remaining instructions, `stringview_wtf16.get_codeunit`, `stringview_wtf16.slice`, and `stringview_wtf16.length` take stringview operands in the stringref proposal but cannot be removed because they lower to operations from the imported strings proposal. These instructions are changed to take stringref operands in Binaryen IR, and to allow a graceful upgrade path for users of these instructions, the text and binary parsers still accept but ignore `string.as_wtf16`, which is the instruction used to convert stringrefs to stringviews. The binary writer emits code sequences that use scratch locals and `string.as_wtf16` to keep the output valid. Future PRs will further align binaryen with the imported strings proposal instead of the stringref proposal, for example by making `string` a subtype of `extern` instead of a subtype of `any` and by removing additional instructions that do not have analogues in the imported strings proposal.
* Source maps: Allow specifying that an expression has no debug info in text ↵Jérôme Vouillon2024-05-141-8/+24
| | | | | | | | | | | | (#6520) ;;@ with nothing else (no source:line) can be used to specify that the following expression does not have any debug info associated to it. This can be used to stop the automatic propagation of debug info in the text parsers. The text printer has also been updated to output this comment when needed.
* [memory64] Add table64 to existing memory64 support (#6577)Sam Clegg2024-05-101-0/+3
| | | | | | | Tests is still very limited. Hopefully we can use the upstream spec tests soon and avoid having to write our own tests for `.set/.set/.fill/etc`. See https://github.com/WebAssembly/memory64/issues/51
* [StackIR] Run StackIR during binary writing and not as a pass (#6568)Alon Zakai2024-05-091-27/+19
| | | | | | | | | | | | | | | | | | | | | | | | | | Previously we had passes --generate-stack-ir, --optimize-stack-ir, --print-stack-ir that could be run like any other passes. After generating StackIR it was stashed on the function and invalidated if we modified BinaryenIR. If it wasn't invalidated then it was used during binary writing. This PR switches things so that we optionally generate, optimize, and print StackIR only during binary writing. It also removes all traces of StackIR from wasm.h - after this, StackIR is a feature of binary writing (and printing) logic only. This is almost NFC, but there are some minor noticeable differences: 1. We no longer print has StackIR in the text format when we see it is there. It will not be there during normal printing, as it is only present during binary writing. (but --print-stack-ir still works as before; as mentioned above it runs during writing). 2. --generate/optimize/print-stack-ir change from being passes to being flags that control that behavior instead. As passes, their order on the commandline mattered, while now it does not, and they only "globally" affect things during writing. 3. The C API changes slightly, as there is no need to pass it an option "optimize" to the StackIR APIs. Whether we optimize is handled by --optimize-stack-ir which is set like other optimization flags on the PassOptions object, so we don't need the old option to those C APIs. The main benefit here is simplifying the code, so we don't need to think about StackIR in more places than just binary writing. That may also allow future improvements to our usage of StackIR.
* Source map fixes (#6550)Jérôme Vouillon2024-05-021-2/+1
| | | | | | | | | | | | | | | | | | | | | | | | | * Keep debug locations at function start The `fn_prolog_epilog.debugInfo` test is failing otherwise, since there was debug information associated to the nop instruction at the beginning of the function. * Do not clear the debug information when reaching the end of the source map The last segment should extend to the end of the function. * Propagate debug location from the function prolog to its first instruction * Fix printing of epilogue location The text parser no longer propagates locations to the epilogue, so we should always print the location if there is one. * Fix debug location smearing The debug location of the last instruction should not smear into the function epilogue, and a debug location from a previous function should not smear into the prologue of the current function.
* Do not repeat types names in text output (#6499)Thomas Lively2024-04-161-2/+35
| | | | | | | | | | For types that do not have explicit names, we generate index-based names in the printer. However, we did not previously ensure that the generated types were not already used as explicit names, so it was possible to print the same name for multiple types, which is not valid. Fix the problem by skipping indices that are already used as type names. Fixes #6492.
* [Strings] Add a string lowering pass using magic imports (#6497)Thomas Lively2024-04-151-5/+8
| | | | | | | | | | | | | | | | | The latest idea for efficient string constants is to encode the constants in the import names of their globals and implement fast paths in the engines for materializing those constants at instantiation time without needing to parse anything in JS. This strategy only works for valid strings (i.e. strings without unpaired surrogates) because only valid strings can be used as import names in the WebAssembly syntax. Add a new configuration of the StringLowering pass that encodes valid string contents in import names, falling back to the JSON custom section approach for invalid strings. To test this chang, update the printer to escape import and export names properly and update the legacy parser to parse escapes in import and export names properly. As a drive-by, remove the incorrect check in the parser that the import module and base names are non-empty.
* Ensure printed tuple.extract arity is valid (#6487)Thomas Lively2024-04-111-1/+6
| | | | | | We previously printed the size of the tuple operand as the arity, but that printed `1` when the operand is unreachable. We don't allow our text input to use `1` as the arity, so don't print it, either. Instead, print the smallest valid arity, `2`, in this case.
* [Strings] Represent string values as WTF-16 internally (#6418)Thomas Lively2024-03-221-1/+7
| | | | | | | | | | | | | | | | WTF-16, i.e. arbitrary sequences of 16-bit values, is the encoding of Java and JavaScript strings, and using the same encoding makes the interpretation of string operations trivial, even when accounting for non-ascii characters. Specifically, use little-endian WTF-16. Re-encode string constants from WTF-8 to WTF-16 in the parsers, then back to WTF-8 in the writers. Update the constructor for string `Literal`s to interpret the string as WTF-16 and store a sequence of WTF-16 code units, i.e. 16-bit integers. Update `Builder::makeConstantExpression` accordingly to convert from the new `Literal` string representation back to a WTF-16 string. Update the interpreter to remove the logic for detecting non-ascii characters and bailing out. The naive implementations of all the string operations are correct now that our string encoding matches the JS string encoding.
* Typed continuations: suspend instructions (#6393)Frank Emrich2024-03-191-0/+5
| | | | | | | | | | | | | | | | | | | | | This PR is part of a series that adds basic support for the [typed continuations/wasmfx proposal](https://github.com/wasmfx/specfx). This particular PR adds support for the `suspend` instruction for suspending with a given tag, documented [here](https://github.com/wasmfx/specfx/blob/main/proposals/continuations/Overview.md#instructions). These instructions are of the form `(suspend $tag)`. Assuming that `$tag` is defined with _n_ `param` types `t_1` to `t_n`, the instruction consumes _n_ arguments of types `t_1` to `t_n`. Its result type is the same as the `result` type of the tag. Thus, the folded textual representation looks like `(suspend $tag arg1 ... argn)`. Support for the instruction is implemented in both the old and the new wat parser. Note that this PR does not implement validation of the new instruction. This PR also fixes finalization of `cont.new`, `cont.bind` and `resume` nodes in those cases where any of their children are unreachable.
* [NFC] Clean up the unreachable replacement code in Print.cpp (#6388)Thomas Lively2024-03-081-108/+56
| | | | | | | When instructions cannot be printed because the children from which they are supposed to get their type immediates are unreachable or null, we print blocks of their dropped children followed by unreachables. But the logic for making this happen was more complicated than necessary and in fact included dead code. Clean it up.
* Fix printing of bulk array ops (#6387)Thomas Lively2024-03-081-0/+19
| | | | | | | | | When the bulk array ops had unreachable or null array types, they were replaced with blocks, but not using the correct code that also prints all their children as dropped followed by an unreachable. This meant that the text output in those cases did not parse as a valid module. Fix the bug. A follow-up PR will simplify the code to prevent similar bugs from occurring in the future.
* Print '(offset ...)` in data and element segments (#6379)Thomas Lively2024-03-061-0/+15
| | | | | | | Previously we just printed the offset instruction(s) directly, which is a valid shorthand only when there is a single instruction. In the case of extended constant instructions, there can potentially be multiple instructions, in which case the explicit `offset` clause is required. Print the full clause when necessary.
* Typed continuations: cont.bind instructions (#6365)Frank Emrich2024-03-041-1/+6
| | | | | | | | | | | | | | | | | | | | | | | | This PR is part of a series that adds basic support for the [typed continuations/wasmfx proposal](https://github.com/wasmfx/specfx). This particular PR adds support for the `cont.bind` instruction for partially applying continuations, documented [here](https://github.com/wasmfx/specfx/blob/main/proposals/continuations/Overview.md#instructions). In short, these instructions are of the form `(cont.bind $ct_before $ct_after)` where `$ct_before` and `$ct_after` are related continuation types. They must only differ in the number of arguments, where `$ct_before` has _n_ additional parameters as compared to `$ct_after`, for some _n_ ≥ 0. The idea is that `(cont.bind $ct_before $ct_after)` then takes a reference to a continuation of type `$ct_before` as well as _n_ operands and returns a (reference to a) continuation of type `$ct_after`. Thus, the folded textual representation looks like `(cont.bind $ct_before $ct_after arg1 ... argn c)`. Support for the instruction is implemented in both the old and the new wat parser. Note that this PR does not implement validation of the new instruction.
* [NFC] Add the type of the Expression when eliding it (#6362)Alon Zakai2024-02-281-1/+2
| | | | | | | | | | In some cases we don't print an Expression in full if it is unreachable, so we print something instead as a placeholder. This happens in unreachable code when the children don't provide enough info to print the parent (e.g. a StructGet with an unreachable reference doesn't know what struct type to use). This PR prints out the name of the Expression type of such things, which can help debugging sometimes.
* Typed continuations: cont.new instructions (#6308)Frank Emrich2024-02-221-0/+5
| | | | | | | | | | | | | | | | | This PR is part of a series that adds basic support for the [typed continuations/wasmfx proposal](https://github.com/wasmfx/specfx). This particular PR adds support for the `cont.new` instruction for creating continuations, documented [here(https://github.com/wasmfx/specfx/blob/main/proposals/continuations/Overview.md#instructions). In short, these instructions are of the form `(cont.new $ct)` where `$ct` must be a continuation type. The instruction takes a single (nullable) function reference as its argument, which means that the folded representation of the instruction is of the form `(cont.new $ct (foo ...))`. Support for the instruction is implemented in both the old and the new wat parser. Note that this PR does not implement validation of the new instruction.
* Properly stringify names in tests (#6279)Thomas Lively2024-02-061-127/+72
| | | | | | | | | | | | | Update identifiers used in tests to use a format supported by the new text parser, i.e. either the standard format with its limited set of allowed characters or the non-standard `$"..."` format. Notably, any name containing square or curly braces now uses the string format. Input automatically updated with this script: https://gist.github.com/tlively/4e22311736661849e641d02e521a0748 The printer is updated to properly escape names in more places as well. The logic for escaping names is moved to a common location so that the type printing logic in wasm-type.cpp can use it as well.
* Update pop text syntax (#6251)Thomas Lively2024-01-291-5/+2
| | | | | | Rather than `(pop valtype*)`, use `(pop valtype)`, where `valtype` is now allowed to be a tuple. This will make it possible to parse un-folded multivalue pops in the new text parser. The alternative would have been to put an arity in the syntax like we have for other tuple instructions, but that's much uglier.
* [EH] Support Stack IR for try_table (#6231)Heejin Ahn2024-01-221-2/+4
|
* Typed continuations: resume instructions (#6083)Frank Emrich2024-01-111-0/+36
| | | | | This PR is part of a series that adds basic support for the [typed continuations proposal](https://github.com/wasmfx/specfx). This particular PR adds support for the `resume` instruction. The most notable missing feature is validation, which is not implemented, yet.
* Require `then` and `else` with `if` (#6201)Thomas Lively2024-01-041-12/+20
| | | | | | | | | | | | We previously supported (and primarily used) a non-standard text format for conditionals in which the condition, if-true expression, and if-false expression were all simply s-expression children of the `if` expression. The standard text format, however, requires the use of `then` and `else` forms to introduce the if-true and if-false arms of the conditional. Update the legacy text parser to require the standard format and update all tests to match. Update the printer to print the standard format as well. The .wast and .wat test inputs were mechanically updated with this script: https://gist.github.com/tlively/85ae7f01f92f772241ec994c840ccbb1
* Use the standard shared memory text format (#6200)Thomas Lively2024-01-031-5/+1
| | | | | Update the legacy text parser and all tests to use the standard text format for shared memories, e.g. `(memory $m 1 1 shared)` rather than `(memory $m (shared 1 1))`. Also remove support for non-standard in-line "data" or "segment" declarations. This change makes the tests more compatible with the new text parser, which only supports the standard format.
* [EH] Misc. fixes for EH (#6195)Heejin Ahn2024-01-021-1/+1
| | | | | - Deletes a stray whitespace after `throw_ref` - Adds missing `makeThrowRef` to `wasm-builder.h` - Adds a case for `TryTable` in `ControlFlowWalker`
* Drop support for non-standard quoted function names (#6188)Thomas Lively2023-12-201-35/+52
| | | | | | | | | | | | | | | | | | We previously supported a non-standard `(func "name" ...` syntax for declaring functions exported with the quoted name. Since that is not part of the standard text format, drop support for it, replacing it with the standard `(func $name (export "name") ...` syntax instead. Also replace our other usage of the quoted form in our text output, which was where we quoted names containing characters that are not allowed to appear in standard names. To handle that case, adjust our output from `"$name"` to `$"name"`, which is the standards-track way of supporting such names. Also fix how we detect non-standard name characters to match the spec. Update the lit test output generation script to account for these changes, including by making the `$` prefix on names mandatory. This causes the script to stop interpreting declarative element segments with the `(elem declare ...` syntax as being named "declare", so prevent our generated output from regressing by counting "declare" as a name in the script.
* [EH] Add instructions for new proposal (#6181)Heejin Ahn2023-12-191-0/+34
| | | | | | | | | | | | | | | | | | | | | | | | This adds basic support for the new instructions in the new EH proposal passed at the Oct CG hybrid CG meeting: https://github.com/WebAssembly/meetings/blob/main/main/2023/CG-10.md https://github.com/WebAssembly/exception-handling/blob/main/proposals/exception-handling/Exceptions.md This mainly adds two instructions: `try_table` and `throw_ref`. This is the bare minimum required to read and write text and binary format, and does not include analyses or optimizations. (It includes some analysis required for validation of existing instructions.) Validation for the new instructions is not yet included. `try_table` faces the same problem with the `resume` instruction in #6083 that without the module-level tag info, we are unable to know the 'sent types' of `try_table`. This solves it with a similar approach taken in #6083: this adds `Module*` parameter to `finalize` methods, which defaults to `nullptr` when not given. The `Module*` parameter is given when called from the binary and text parser, and we cache those tag types in `sentTypes` array within `TryTable` class. In later optimization passes, as long as they don't touch tags, it is fine to call `finalize` without the `Module*`. Refer to https://github.com/WebAssembly/binaryen/pull/6083#issuecomment-1854634679 and #6096 for related discussions when `resume` was added.