summaryrefslogtreecommitdiff
path: root/src
Commit message (Collapse)AuthorAgeFilesLines
...
* [Parser] Support loops (#5966)Thomas Lively2023-09-214-33/+109
| | | Parse loops in the new wat parser and add support for them to the IRBuilder.
* [Parser] Allow any number of foldedinsts in `foldedinsts` (#5965)Thomas Lively2023-09-213-60/+79
| | | | | | Somewhat counterintuitively, the text syntax for a folded `if` allows any number of folded instructions in the condition position, not just one. Update the corresponding `foldedinsts` parsing function to parse arbitrary sequences of folded instructions and add a test.
* [NFC][Parser] Simplify instruction handling (#5964)Thomas Lively2023-09-215-2346/+1554
| | | | | | | | | | | The new wat parser previously returned InstrT types when parsing individual instructions and collected InstrsT types when parsing sequences of instructions. However, instructions were always actually tracked in the internal state of the parsing context, so these types never held any interesting or necessary data. Simplify the parser by removing these types and leaning into the pattern that the parser context will keep track of parsed instructions. This allows for a much cleaner separation between the `instrs` and `foldedinstrs` parser functions.
* [Parser] Parse if-else in the new wat parser and IRBuilder (#5963)Thomas Lively2023-09-215-72/+341
| | | | | | Parse both the straight-line and folded versions of if, including the abbreviations that allow omitting the else clause. In the IRBuilder, generalize the scope stack to be able to track scopes other than blocks and add methods for visiting the beginnings of ifs and elses.
* Support i8/i16 mutable arrays as public types for string interop (#5814)Alon Zakai2023-09-214-1/+47
| | | | | Probably any array of non-reference data can be allowed to be public and sent out of the module, as it is just data. For now, however, just special case the i8 and i16 array types which are useful already for string interop.
* Make heap2local work through casts (#5952)Jérôme Vouillon2023-09-211-2/+26
| | | | | | | | | | | | | | | | | | | | | E.g. (local $x (ref eq) ... (local.set $x (struct.new $float ... ) ) (struct.get $float 0 (ref.cast (ref $float) (local.get $x) ) ) This PR allows us to use heap2local, ignoring the passing cast. This is similar to existing handling of ref.as_non_null.
* Error on multivalue inputs that we do not handle (#5962)Alon Zakai2023-09-201-2/+6
| | | | | | Before in getType() we silently dropped the params of a signature type. Now we verify that it is none, or we error. Helps #5950
* [NFC] RemoveUnusedModuleElements: Use delegations (#5961)Alon Zakai2023-09-191-93/+41
| | | | NFC, but fixes a current fuzz bug on table.fill not having an entry in this file. After this PR, there is no need for such entries.
* [NFC] Split the new wat parser into multiple files (#5960)Thomas Lively2023-09-1913-1899/+2197
| | | | | | And put the new files in a new source directory, "parser". This is a rough split and is not yet expected to dramatically improve compile times. The exact organization of the new files is subject to change, but this splitting should be enough to make further parser development more pleasant.
* Reland "Optimize tuple.extract of gets in BinaryInstWriter" (#5955)Thomas Lively2023-09-182-1/+47
| | | | | | | | | In general, the binary lowering of tuple.extract expects that all the tuple values are on top of the stack, so it inserts drops and possibly uses a scratch local to ensure only the extracted value is left. However, when the extracted tuple expression is a local.get, local.tee, or global.get, it's much more efficient to change the lowering of the get or tee to ensure that only the extracted value is on the stack to begin with. Implement that optimization in the binary writer.
* Do not optimize tuple locals in StackIR local2stack (#5958)Thomas Lively2023-09-181-1/+5
| | | | This Stack IR optimization is not compatible with a much more powerful optimization we plan to do for tuples in the binary writer.
* Fix visitBlock and add visitBlockStart in IRBuilder (#5959)Thomas Lively2023-09-192-9/+19
| | | | | | | | | | Visiting a block should push it onto the stack just like visiting any other expression, but we previously had a `visitBlock` that introduced a new scope instead. Fix `visitBlock` to behave as expected and introduce a new `visitBlockStart` method to introduce a new scope. Unfortunately this cannot be fully tested yet because the wat parser uses the `makeXYZ` API intead of the `visit` API, but at least I updated `makeBlock` to call `visitBlockStart`, so that is tested.
* Add passes to finalize or unfinalize types (#5944)Alon Zakai2023-09-186-0/+108
| | | | | | | | | TypeFinalization finalizes all types that we can, that is, all private types that have no children. TypeUnFinalization unfinalizes (opens) all (private) types. These could be used by first opening all types, optimizing, and then finalizing, as that might find more opportunities. Fixes #5933
* TupleOptimization: Handle copies of different types in unreachable code (#5956)Alon Zakai2023-09-181-4/+12
|
* Fix validation error message for table.fill (#5953)Thomas Lively2023-09-181-4/+3
| | | table.fill requires bulk memory to be enabled, not reference types.
* Implement table.fill (#5949)Thomas Lively2023-09-1821-0/+175
| | | | | | | | This instruction was standardized as part of the bulk memory proposal, but we never implemented it until now. Leave similar instructions like table.copy as future work. Fixes #5939.
* Remove legacy type defintion text syntax (#5948)Thomas Lively2023-09-181-40/+4
| | | | | | | Remove support for the "struct_subtype", "array_subtype", "func_subtype", and "extends" notations we used at various times to declare WasmGC types, leaving only support for the standard text fromat for declaring types. Update all the tests using the old formats and delete tests that existed solely to test the old formats.
* Revert "Optimize tuple.extract of gets in BinaryInstWriter (#5941)" (#5945)Thomas Lively2023-09-142-47/+1
| | | | | This reverts commit 56ce1eaba7f500b572bcfe06e3248372e9672322. The binary writer optimization is not always correct when stack IR optimizations have run. Revert the change until we can fix it.
* Optimize tuple.extract of gets in BinaryInstWriter (#5941)Thomas Lively2023-09-142-1/+47
| | | | | | | | | In general, the binary lowering of tuple.extract expects that all the tuple values are on top of the stack, so it inserts drops and possibly uses a scratch local to ensure only the extracted value is left. However, when the extracted tuple expression is a local.get, local.tee, or global.get, it's much more efficient to change the lowering of the get or tee to ensure that only the extracted value is on the stack to begin with. Implement that optimization in the binary writer.
* Add a simple tuple optimization pass (#5937)Alon Zakai2023-09-144-0/+370
| | | | | | | | | | | In some cases tuples are obviously not needed, such as when they are only used in local operations and make/extract. Such tuples are not used as return values or in control flow structures, so we might as well lower them to individual locals per lane, which other passes can optimize a lot better. I believe LLVM does the same with its own tuples: it lowers them as much as possible, leaving only necessary ones. Fixes #5923
* Encode command line to UTF8 on Windows (#5671)Derek Schuff2023-09-146-15/+98
| | | | | | | | | | | | | | | | This PR changes how file paths and the command line are handled. On startup on Windows, we process the wstring version of the command line (including the file paths) and re-encode it to UTF8 before handing it off to the rest of the command line handling logic. This means that all paths are stored in UTF8-encoded std::strings as they go through the program, right up until they are used to open files. At that time, they are converted to the appropriate native format with the new to_path function before passing to the stdlib open functions. This has the advantage that all of the non-file-opening code can use a single type to hold paths (which is good since std::filesystem::path has proved problematic in some cases), but has the disadvantage that someone could add new code that forgets to convert to_path before opening. That's somewhat mitigated by the fact that most of the code uses the ModuleIOBase classes for opening files. Fixes #4995
* OptimizeInstructions: Simplify tuple.extract of tuple.make (#5938)Alon Zakai2023-09-141-0/+19
| | | | | | | | | | | | | | E.g. (tuple.extract 1 (tuple.make (A) (B) (C)) => (B) Modify some existing tests to not be in this trivial form, so that they do not stop testing what they should.
* Replace i31.new with ref.i31 everywhere (#5931)Thomas Lively2023-09-137-19/+39
| | | | | Replace i31.new with ref.i31 in the printer, tests, and source code. Continue parsing i31.new for the time being to allow a graceful transition. Also update the JS API to reflect the new instruction name.
* Avoid off_t in small_vector.h (#5936)Alon Zakai2023-09-131-1/+3
| | | | Fixes #5928 , on FreeBSD off_t is not defined in the headers we include.
* Replace I31New with RefI31 everywhere (#5930)Thomas Lively2023-09-1328-72/+72
| | | | | | | | Globally replace the source string "I31New" with "RefI31" in preparation for renaming the instruction from "i31.new" to "ref.i31", as implemented in the spec in https://github.com/WebAssembly/gc/pull/422. This would be NFC, except that it also changes the string in the external-facing C APIs. A follow-up PR will make the corresponding behavioral change.
* Use standard GC encodings by default (#5873)Thomas Lively2023-09-121-4/+3
| | | | The legacy encodings remain available for now by defining USE_LEGACY_GC_ENCODINGS at build time.
* Remove legacy GC text syntax (#5929)Thomas Lively2023-09-122-44/+4
| | | | Remove the old forms of ref.test and ref.cast that took heap types instead of ref types and remove the old array.init_static name for array.new_fixed.
* Fix printing of types for imported functions (#5927)Thomas Lively2023-09-111-1/+1
| | | | | | Previously, the printer incorrectly reconstructed imported functions' types from their signatures instead of printing their types directly. This could cause the printer to print uses of types that were never defined and did not exist in the module. Fix the bug by printing imported functions' heap types directly.
* Make final types the default (#5918)Thomas Lively2023-09-0912-35/+47
| | | | | | | | | | | | | Match the spec and parse the shorthand binary and text formats as final and emit final types without supertypes using the shorthands as well. This is a potentially-breaking change, since the text and binary shorthands can no longer be used to define types that have subtypes. Also make TypeBuilder entries final by default to better match the spec and update the internal APIs to use the "open" terminology rather than "final" terminology. Future changes will update the text format to use the standard "sub open" rather than the current "sub final" keywords. The exception is the new wat parser, which supporst "sub open" as of this change, since it didn't support final types at all previously.
* [NFC] Source maps: Simplify the code and add comments (#5912)Alon Zakai2023-09-062-37/+46
| | | | | | | | | | | | | | | Almost entirely trivial, except for this part: - if (nextDebugLocation.availablePos == 0 && - nextDebugLocation.previousPos <= pos) { + if (nextDebugLocation.availablePos == 0) { return; I believe removing the extra check has no effect. Removing it does not change anything in the test suite, and logically, if we set availablePos to 0 then we definitely want to return here - we set it to 0 to indicate there is nothing left to read, which is what the code after it does. As a result, we can remove the previousPos field entirely.
* DebugInfo: Don't trample in replaceCurrent() (#5915)Alon Zakai2023-08-311-1/+6
| | | | | | Copy the old expression's debug info if the new has none. But if the new has its own, trust that. Followup to #5914
* DebugInfo: Fix loss of debug info in replaceCurrent() (#5914)Alon Zakai2023-08-311-3/+18
| | | | | | | | | | | | | | | | | The logic there assumed that we are removing the current node and replacing it with the given one, so it copied debug info to the new one and deleted it for the old. But the old one might now be a child of the new one, if we reordered, so we were dropping debug info, in particular in MergeBlocks which reorders like this: (call (block .. => (block (call (it moves blocks outwards so it can merge them).
* Remove the GCNNLocals feature (#5080)Thomas Lively2023-08-318-124/+28
| | | | | Now that the WasmGC spec has settled on a way of validating non-nullable locals, we no longer need this experimental feature that allowed nonstandard uses of non-nullable locals.
* Parse non-nullable tuple elements without special handling (#5910)Thomas Lively2023-08-301-23/+5
| | | | | | | In the binary parser, when creating a scratch local to hold multivalue results as tuples, we previously ensured that the scratch local did not contain any non-nullable by modifying its type and inserting ref.as_non_null as necessary. Now that we properly support non-nullable elements in tuple locals, however, this parser behavior is no longer necessary. Remove it.
* Source maps: Fix locations without debug info between ones that do (#5906)Alon Zakai2023-08-302-14/+75
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Previously we did nothing for instructions without debug info. So if we had one that did, followed by one that didn't, the one that didn't could get "smeared" with the debug info of the first. Source map locations are the start of segments, apparently, and so if we say a location has info then all others after it will as well, until the next segment. To fix that, add support for source map entries with just one field, the binary location. Such entries have no debug info (no file:line:col), and though the source maps spec is not very clear on this, this seems like the right way to prevent this problem: to stop a segment with debug info by starting a new one without, when we know we don't want that info any more. That is, before this PR we could have this: ;; file.cpp:10:1 (nop) ;; binary offset 5 in wasm (nop) ;; binary offset 6 in wasm and the second nop would get the same debug annotation, since we just have one source map segment, [5, file.cpp, 10, 1] // start at offset 5 in wasm With this PR, we emit: [5, file.cpp, 10, 1] // start at offset 5 in wasm; file.cpp:10:1 [6] // start at offset 6 in wasm; no debug info This does add 7% to source map sizes, however, since we add those 1-length segments now, but that seems unavoidable to fix this bug. To implement this, add a new field that says if the next location in the source map has debug info or not, and use that.
* Validate and fix up tuples with non-nullable elements (#5909)Thomas Lively2023-08-303-27/+87
| | | | | | The code validating and fixing up non-nullable locals previously did not correctly handle tuples that contained non-nullable elements, which could have resulted in invalid modules going undetected. Update the code to handle tuples and add tests.
* Print all debug annotations when BINARYEN_PRINT_FULL (#5904)Alon Zakai2023-08-291-1/+22
| | | | | | | | In general, full print mode should print out all the things to avoid confusion. It already did so for blocks (that the text format sometimes elides), types, etc. Doing it for debug info can avoid confusion when debugging (in fact, this was one of the main reasons I've been confused about how source maps work in Binaryen...). Also add a comment to the code just landed in #5903
* Fix standard reference type encoding (#5905)Thomas Lively2023-08-281-2/+2
| | | | This bug was found by fuzzing Binaryen and V8 together with the standard GC encodings enabled.
* Improve debug info printing with depth (#5903)JesseChen2023-08-281-1/+4
| | | | | | Skip repeated identical debug info only of more-nested nodes. Before this PR we skipped sibling nodes and even parent nodes, which could be confusing. After this PR there is a more clear connection: child nodes have the same debug location as the parent, by default, and so there is no need to print it again.
* Refactor IRBuilder to build blocks internally (#5901)Thomas Lively2023-08-283-238/+349
| | | | | | | | | | | | | The initial PR introducing IRBuilder kept the interface the same as the previous internal interface in the new wat parser. This PR updates that interface to avoid exposing implementation details of the IRBuilder and to provide an API that matches the binary format. For example, after calling `makeBlock` or `visitBlock` at the beginning of a block, users now call `visitEnd()` at the end of the block without having to manually install the block's contents. Providing this improved interface requires refactoring some of the IRBuilder internals. While we are refactoring things anyway, put in extra effort to avoid unnecessarily splitting up and recombining tuples that could simply be returned from a multivalue block.
* GlobalStructInference: Add missing ReFinalize (#5898)Alon Zakai2023-08-241-1/+17
|
* Simplify and consolidate type printing (#5816)Thomas Lively2023-08-242-1223/+997
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | When printing Binaryen IR, we previously generated names for unnamed heap types based on their structure. This was useful for seeing the structure of simple types at a glance without having to separately go look up their definitions, but it also had two problems: 1. The same name could be generated for multiple types. The generated names did not take into account rec group structure or finality, so types that differed only in these properties would have the same name. Also, generated type names were limited in length, so very large types that shared only some structure could also end up with the same names. Using the same name for multiple types produces incorrect and unparsable output. 2. The generated names were not useful beyond the most trivial examples. Even with length limits, names for nontrivial types were extremely long and visually noisy, which made reading disassembled real-world code more challenging. Fix these problems by emitting simple indexed names for unnamed heap types instead. This regresses readability for very simple examples, but the trade off is worth it. This change also reduces the number of type printing systems we have by one. Previously we had the system in Print.cpp, but we had another, more general and extensible system in wasm-type-printing.h and wasm-type.cpp as well. Remove the old type printing system from Print.cpp and replace it with a much smaller use of the new system. This requires significant refactoring of Print.cpp so that PrintExpressionContents object now holds a reference to a parent PrintSExpression object that holds the type name state. This diff is very large because almost every test output changed slightly. To minimize the diff and ease review, change the type printer in wasm-type.cpp to behave the same as the old type printer in Print.cpp except for the differences in name generation. These changes will be reverted in much smaller PRs in the future to generally improve how types are printed.
* Fix merging of unrelated types in TypeMerging (#5897)Thomas Lively2023-08-231-7/+69
| | | | | | | | | Previously it was possible that the supertype merging phase would merge unrelated types when DFA minimization would split a common supertype out of a partition, leaving unrelated types behind in the same partition. Fix the problem by post-processing the partitions in the supertype merging phase to split any partitions that contain unrelated types. Fixes #5877.
* SignatureRefining: Handle updates to call.without.effects (#5884)Alon Zakai2023-08-231-0/+68
| | | | | | | If we refine a signature type that is used in a call.without.effects then that call's results may need to be updated. In the IR it looks like a normal call that happens to pass a function reference as the last param, but it actually means that we call that function (without side effects), so we need to have the same results, and the validator already verified that (so the new testcase here fails without this fix).
* Use the standard syntax for ref.cast, ref.test and array.new_fixed (#5894)Jérôme Vouillon2023-08-231-10/+5
| | | | | | | | | * Update text output for `ref.cast` and `ref.test` * Update text output for `array.new_fixed` * Update tests with new syntax for `ref.cast` and `ref.test` * Update tests with new `array.new_fixed` syntax
* Fix assertion failure in RemoveUnusedBrs (#5895)Thomas Lively2023-08-231-0/+4
| | | | | | | | The improvements to RemoveUnusedBrs in #5887 also introduced a regression where the pass did not correctly handle unreachable fallthrough values and crashed with an assertion failure. Fix the problem by returning early when a fallthrough value is unreachable and add a regression test. Fixes #5892.
* wasm-ctor-eval: Limit memory to a reasonable amount (#5896)Alon Zakai2023-08-231-0/+11
| | | | | | In practice we don't need high addresses, and when they happen the current implementation can OOM, so exit early on them instead. Fixes #5893
* Update stringref text format (#5891)Jérôme Vouillon2023-08-223-90/+262
| | | | | | | | | | | * Allow new syntax for some stringref opcodes Fixes #5607 * Update stringref text output * Update tests with new syntax for stringref opcodes Except in test/lit/strings.wat, to check that the legacy syntax still works.
* Factor IRBuilder utility out of the new wat parser (#5880)Thomas Lively2023-08-227-491/+1046
| | | | | | | | | | | | | | | | | | | | | | | | | | | Add an IRBuilder utility in a new wasm-ir-builder.h header. IRBuilder is extremely similar to Builder, except that it manages building full trees of Binaryen IR from a linear sequence of instructions, whereas Builder only builds a single IR node at a time. To build full IR trees, IRBuilder maintains an internal stack of expressions, popping children off the stack and pushing the new node onto the stack whenever it builds a new node. In addition to providing makeXYZ function to allocate, initialize, and finalize new IR nodes, IRBuilder also provides a visit() method that can be used when the user has already allocated the IR nodes and only needs to reconstruct the connections between them. This will be useful in outlining both for constructing outlined functions and for reconstructing functions around arbitrary outlined holes. Besides the new wat parser and outlining, this new utility can also eventually be used in the binary parser and to convert from Poppy IR back to Binaryen IR if that ever becomes necessary. To simplify this initial change, IRBuilder exposes the same interface as the code it replaces in the wat parser. A future change requiring more extensive changes to the wat parser will simplify this interface. Also, since the new code is tested only via the new wat parser, it only supports building instructions that were already supported by the new wat parser to avoid trying to support any instructions without corresponding testing. Implementing support for the remaining instructions is left as future work.
* Make the legacy parser follow more closely the standard GC text format (#5889)Jérôme Vouillon2023-08-221-13/+37
| | | | | | | | | | | * Allow empty `then` and `else` clauses * Allow standard syntax for `ref.test` and `ref.cast` Fixes #5795 * Allow size immediate in `array.new_fixed` Fixes #5769