summaryrefslogtreecommitdiff
path: root/src
Commit message (Collapse)AuthorAgeFilesLines
...
* 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
* Rename multimemory flag (#5890)Ashley Nelson2023-08-2114-27/+27
| | | Renaming the multimemory flag in Binaryen to match its naming in LLVM.
* Improve br_on* optimizations (#5887)Thomas Lively2023-08-221-35/+141
| | | | | | | Optimize both the known-null and known-non-null cases for BrOnNull and BrOnNonNull and optimize for more cast behaviors such as SuccessOnlyIfNonNull and Unreachable for BrOnCast and BrOnCastFail. Leave optimizing SuccessOnlyIfNull to future work, since that's more complicated. Use type information from fallthrough values to inform all the optimizations.
* Fix finalization of call_ref to handle refined target types (#5883)Thomas Lively2023-08-214-8/+22
| | | | | | | | | | Previously CallRef::finalize() would never update the type of the CallRef, even if the type of the call target had been refined to give a more precise result type. Besides unnecessarily losing type information, this could also lead to validation errors, since the validator checks that the type of CallRef matches the result type of the target signature. Fix the bug by updating CallRef's type based on its target signature in CallRef::finalize() and add a test that depends on this refinalization.
* Fix SSA on null refinement (#5886)Alon Zakai2023-08-171-0/+11
| | | | Similar to #5885 this was uncovered by #5881 #5882. Here we need to refinalize when we replace a local.get with a null, since the null's type is more refined.
* ReFinalize in TypeSSA (#5885)Alon Zakai2023-08-171-0/+4
| | | | This has been a bug for a while but it became noticeable after #5881 #5882 which do more work in refinalization.
* Further improve ref.cast during finalization (#5882)Thomas Lively2023-08-171-16/+11
| | | | | | We previously improved the nullability and heap type of the ref.cast target type in RefCast::finalize() based on what we knew about its input type. Simplify the code and make this improvement more powerful by using the greatest lower bound of the original cast target and input type.
* Ensure br_on_cast* target type is subtype of input type (#5881)Thomas Lively2023-08-175-0/+22
| | | | | | | | | | | | | | | | The WasmGC spec will require that the target cast type of br_on_cast and br_on_cast_fail be a subtype of the input type, but so far Binaryen has not enforced this constraint, so it could produce invalid modules when optimizations refined the input to a br_on_cast* such that it was no longer a supertype of the cast target type. Fix this problem by setting the cast target type to be the greatest lower bound of the original cast target type and the current input type in `BrOn::finalize()`. This maintains the invariant that the cast target type should be a subtype of the input type and it also does not change cast behavior; any value that could make the original cast succeed at runtime necessarily inhabits both the original cast target type and the input type, so it also must inhabit their greatest lower bound and will make the updated cast succeed as well.
* Improve cast optimizations (#5876)Thomas Lively2023-08-174-158/+243
| | | | | | | | | | | | Simplify the optimization of ref.cast and ref.test in OptimizeInstructions by moving the loop that examines fallthrough values one at a time out to a shared function in properties.h. Also simplify ref.cast optimization by analyzing the cast result in just one place. In addition to simplifying the code, also make the cast optimizations more powerful by analyzing the nullability and heap type of the cast value independently, resulting in a potentially more precise analysis of the cast behavior. Also improve optimization power by considering fallthrough values when optimizing the SuccessOnlyIfNonNull case.
* Heap2Local: Refinalize if we end up refining (#5879)Alon Zakai2023-08-171-5/+28
| | | | | | | | We shouldn't need to in the general case, but the fuzzer found a corner case where we do need to, see the explanation + testcase, but basically Heap2Local replaces struct fields with locals, and the locals should have the same types, but if a field was somehow less refined for some reason, then the locals could actually be more refined. (And a field could be less refined if we read it from a typed that was under-refined due to a tee or such.)
* [NFC] Factor `Result` and `MaybeResult` into a utility header (#5878)Thomas Lively2023-08-143-54/+88
| | | Allow them to be used for more than just the new text parser.
* Allow opting into standard GC encodings at compile time (#5868)Thomas Lively2023-08-101-49/+153
| | | | | | | | | | | Depending on whether preprocessor macros USE_STANDARD_GC_ENCODINGS and USE_LEGACY_GC_ENCODINGS are defined, use the standard or legacy encodings for GC types and instructions. Default to the latter for now. When WasmGC reaches phase 4, we will switch the default to be the standard encodings instead. After users have time to update, we will remove the legacy encodings entirely. Tested manually by building with USE_STANDARD_GC_ENCODINGS locally and seeing that all the tests pass except for some tests that depend on the specific binary encoding.
* Remove legacy WasmGC instructions (#5861)Thomas Lively2023-08-0917-550/+130
| | | | | Remove old, experimental instructions and type encodings that will not be shipped as part of WasmGC. Updating the encodings and text format to match the final spec is left as future work.
* LinearExecutionWalker: Optionally connect blocks for Br and BrOn (#5869)Alon Zakai2023-08-091-4/+13
| | | | | | | | | | | | | | | | | | | Br and BrOn can consider the code before and after them connected if it might be reached (which is the case if the Br has a condition, which BrOn always has). The wasm2js changes may look a little odd as some of them have this: i64toi32_i32$1 = i64toi32_i32$2; i64toi32_i32$1 = i64toi32_i32$2; I looked into that and the reason is that those outputs are not optimized, and also even in unoptimized wasm2js we do run simplify-locals once (to try to reduce the downsides of flatten). As a result, this PR makes a difference there, and that difference can lead to such odd duplicated code after other operations. However, there are no changes to optimized wasm2js outputs, so there is no actual problem. Followup to #5860.
* OptimizeCasts: Connect adjacent blocks in LinearExecutionWalker (#5866)Alon Zakai2023-08-081-0/+10
| | | | | | | Followup to #5860, this does the same for (part of) OptimizeCasts. As there, this is valid because it's ok if we branch away. This part of the pass picks a different local to get when it knows locals have the same values but one is more refined. It is ok to add a tee earlier even if it isn't used later.
* LocalCSE: Connect adjacent blocks in LinearExecutionWalker (#5867)Alon Zakai2023-08-081-0/+11
| | | | | | | Followup to #5860, this does the same for LocalCSE. As there, this is valid because it's ok if we branch away. This pass adds a local.tee of a reused value and then gets it later, and it's ok to add a tee even if we branch away and do not use it.
* SimplifyGlobals: Connect adjacent blocks in LinearExecutionWalker (#5865)Alon Zakai2023-08-081-0/+5
| | | | | | | Followup to #5860, this does the same for SimplifyGlobals as for SimplifyLocals. As there, this is valid because it's ok if we branch away. This part of the pass applies a global value to a global.get based on a dominating global.set, so any dominance is good enough for us.
* LinearExecutionTraversal: Add an option to connect adjacent code, use in ↵Alon Zakai2023-08-082-5/+47
| | | | | | | | | | | SimplifyLocals (#5860) This addresses most of the minor regression from the correctness fix in #5857. That PR makes us consider calls as branching, but in some cases it is ok to ignore that branching (see the comment in the code here), which this PR allows as an option. This undoes one test change from that PR, showing it undoes the regression for SimplifyLocals. More tests are added to cover this specifically as well.
* Fix LinearExecutionWalker on calls (#5857)Alon Zakai2023-08-072-6/+26
| | | | | | | | | | | | | | Calls were simply not handled there, so we could think we were still in the same basic block when we were not, affecting various passes (but somehow this went unnoticed until the TNHOracle #5850 ran on some particular Java code). One existing test was affected, and two new tests are added: one for TNHOracle where I detected this, and one in OptimizeCasts which is perhaps a simpler way to see the problem. All the cases but the TNH one, however, do not need this fix for correctness since they actually don't care if a call would throw. As a TODO, we should find a way to undo this minor regression. The regression only affects builds with EH enabled, though, so most users should be unaffected even in the interm.
* Lattice to model Stack (#5849)Bruce He2023-08-034-9/+329
| | | | | | | | | | | | | | | | | This change introduces StackLattice, a lattice to model stack-related behavior. It is templated on a separate lattice whose elements model some property of individual values on the stack. The StackLattice allows users to access the top of the stack, push abstract values, and pop them. Comparisons and least upper bound operations are done on a value by value basis starting from the top of the stack and moving toward the bottom. This is because it allows stacks from different scopes to be joined easily. An application of StackLattice is to model the wasm value stack. The goal is to organize lattice elements representing individual stack values in a natural way which mirrors the wasm value stack. Transfer functions operate on each stack value individually. The stack lattice is an intermediate structure which is not intended to be directly operated on. Rather, it simulates the push and pop behavior of instructions.
* [Outlining] Integration test for suffix_tree and stringify (#5839)Ashley Nelson2023-08-031-0/+11
| | | Adds an integration test that identifies the substrings of a stringified wasm module using the suffix_tree.