This is in preparation for the argument mutability analysis. This PR
also has some skeleton code for this analysis, but the actual analysis
is still a `todo!()`.
The analysis will also have better precision if we use fewer asm blocks,
but I'll get to that after working on the analysis itself.
## Description
Whilst finishing "const generics" I spent a LOT of time trying to find
why some cases where not working. Until I found the issue on a "indirect
input" for the method `type_check_method_application`.
The issue is that some other method was returning a wrong value, and
although the solution is not hard, there is no way to fix just this
problem, and there is no way to assert this returned value to guarantee
that the problem will not return.
To start to improve these kind of tests, and help debug problems, this
PR start to create a "callback" mechanism that allows anyone using the
compiler as a library, this will not be available at the CLI, to inspect
and control logging.
The integration in out e2e test harness is done by the `test.toml`.
```
category = "run"
expected_result = { action = "return", value = 1 }
expected_result_new_encoding = { action = "return_data", value = "0000000000000001" }
validate_abi = true
logs = """
if pkg != "std" && event == "on_before_method_resolution" && method == "len_xxx" {
print_args();
trace(true);
}
if pkg != "std" && event == "on_after_method_resolution" && method == "len_xxx" {
print_args();
trace(false);
}
"""
```
The `harness` framework will not call "logs" for every callback that
happens outside of the "std" library. To allow interaction with the
harness itself, some commands are available:
- `print_args` print all the available arguments for that event on the
"snapshot";
- `trace` enables/disables trace level logging, that also end up in the
"snapshot".
In the example above, we will generate the following snapshot:
```
---
source: test/src/e2e_vm_tests/harness_callback_handler.rs
assertion_line: 14
---
on_before_method_resolution: FromModule { method_name: len_xxx }; Regular([]); S<unresolved T -> u64, N -> 3>
before get_method_safe_to_unify: S<unresolved T -> u64, N -> 3> len_xxx<N -> None>(self: unresolved Self -> S<unresolved T -> T, N -> None>): u64 -> u64
after get_method_safe_to_unify: S<unresolved T -> u64, N -> 3>; len_xxx<N -> 3>(self: unresolved Self -> S<unresolved T -> u64, N -> None>): u64 -> u64
on_after_method_resolution: FromModule { method_name: len_xxx }; Regular([]); S<unresolved T -> u64, N -> 3>; len_xxx<N -> 3>(self: unresolved Self -> S<unresolved T -> u64, N -> None>): u64 -> u64; S<unresolved T -> u64, N -> 3>
on_before_method_resolution: FromModule { method_name: len_xxx }; Regular([]); S<unresolved T -> u64, N -> 3>
before get_method_safe_to_unify: S<unresolved T -> u64, N -> 3> len_xxx<N -> None>(self: unresolved Self -> S<unresolved T -> T, N -> None>): u64 -> u64
after get_method_safe_to_unify: S<unresolved T -> u64, N -> 3>; len_xxx<N -> 3>(self: unresolved Self -> S<unresolved T -> u64, N -> None>): u64 -> u64
```
The important part is that the problem I want to fix it's there. On the
line of "get_method_safe_to_unify", the "self" parameter const generic
argument "N" is not being materialized, although the method resolution
pass started with a fully materialized type.
With this callback machinery it becomes easier to debug the problems,
and possible to generate asserts to internal methods.
## Checklist
- [x] I have linked to any relevant issues.
- [x] I have commented my code, particularly in hard-to-understand
areas.
- [ ] I have updated the documentation where relevant (API docs, the
reference, and the Sway book).
- [ ] If my change requires substantial documentation changes, I have
[requested support from the DevRel
team](https://github.com/FuelLabs/devrel-requests/issues/new/choose)
- [x] I have added tests that prove my fix is effective or that my
feature works.
- [ ] I have added (or requested a maintainer to add) the necessary
`Breaking*` or `New Feature` labels where relevant.
- [x] I have done my best to ensure that my PR adheres to [the Fuel Labs
Code Review
Standards](https://github.com/FuelLabs/rfcs/blob/master/text/code-standards/external-contributors.md).
- [ ] I have requested a review from the relevant team or maintainers.
## Description
This PR contains an initial implementtion of subroutine calls using the
in-progress [jump-and-link instruction
`JAL`](https://github.com/FuelLabs/fuel-specs/pull/630). It
substantially reduces the function call overhead: the old code used 4
instructions per call, while the new version uses 1-3 depending on the
distance to the called function.
### Future optimizations
* Reorder functions, so those that call each other are adjacent
* Use absolute or IS-relative jumps where it makes sense, see
https://github.com/FuelLabs/sway/issues/7267
## Checklist
- [x] I have linked to any relevant issues.
- [x] I have commented my code, particularly in hard-to-understand
areas.
- [ ] I have updated the documentation where relevant (API docs, the
reference, and the Sway book).
- [x] If my change requires substantial documentation changes, I have
[requested support from the DevRel
team](https://github.com/FuelLabs/devrel-requests/issues/new/choose)
- [x] I have added tests that prove my fix is effective or that my
feature works.
- [x] I have added (or requested a maintainer to add) the necessary
`Breaking*` or `New Feature` labels where relevant.
- [x] I have done my best to ensure that my PR adheres to [the Fuel Labs
Code Review
Standards](https://github.com/FuelLabs/rfcs/blob/master/text/code-standards/external-contributors.md).
- [x] I have requested a review from the relevant team or maintainers.
The goal of this PR is to enable the check in the IR verifier to ensure
that the operand to `ptr_to_int` instructions can only be pointers. The
other changes are to support that.
## Description
Bumps fuel-vm, fuel-core fuels-rs and forc-wallet to latest versions.
Upgrades Rust to 2021 edition.
## Checklist
- [x] I have linked to any relevant issues.
- [x] I have commented my code, particularly in hard-to-understand
areas.
- [x] I have updated the documentation where relevant (API docs, the
reference, and the Sway book).
- [x] If my change requires substantial documentation changes, I have
[requested support from the DevRel
team](https://github.com/FuelLabs/devrel-requests/issues/new/choose)
- [x] I have added tests that prove my fix is effective or that my
feature works.
- [ ] I have added (or requested a maintainer to add) the necessary
`Breaking*` or `New Feature` labels where relevant.
- I believe this is non-breaking from user code perspective but I'm not
too sure about that
- [x] I have done my best to ensure that my PR adheres to [the Fuel Labs
Code Review
Standards](https://github.com/FuelLabs/rfcs/blob/master/text/code-standards/external-contributors.md).
- [x] I have requested a review from the relevant team or maintainers.
---------
Co-authored-by: z <zees-dev@users.noreply.github.com>
Co-authored-by: zees-dev <63374656+zees-dev@users.noreply.github.com>
Co-authored-by: JoshuaBatty <joshpbatty@gmail.com>
Co-authored-by: IGI-111 <igi-111@protonmail.com>
## Description
This is the third PR to address #6351. It allows safely taking addresses
of function arguments, and represents references (`&`) as pointers in
the IR.
Note: The entire function `type_correction` (in `ir_generation.rs`) and
this
[edit](2de7ab9ec1 (diff-3b0502f41aeb3c45ddbdb3cc590658d73d2bd7283671eb6d789d7e77a7dd2596R670))
in `compile.rs`, to handle return values, must be removed once we fix
and finalize the syntax of references. Until then these two hacks need
to stay. Ideally I wanted to put them both in one place (which is the
`type_correction` pass), but the return type fix needs to happen,
unfortunately, during IR gen.
---------
Co-authored-by: IGI-111 <igi-111@protonmail.com>
Co-authored-by: Igor Rončević <ironcev@hotmail.com>
## Description
This PR adds support for ABI errors in `forc test`. If a unit test
reverts, the received revert code is inspected for known error signals
(e.g., coming from `assert`, or `require`) and for ABI errors.
Analysis of the received revert code is encapsulated within the
`forc_util::tx_utils::RevertInfo` struct implementation. This way, it
can be reused between the `forc test` and `forc call`. However, on the
long term, this abstraction should be moved to `fuel-abi-types`, because
its whole logic is ABI related, and it should also be shareable with the
Rust SDK.
The reason for temporary placing it within `forc-util` crate is to get
the support for ABI errors in `forc test` in the next Sway release,
without the need for a new `fuel-abi-types` release that triggers the
circular dependency between Sway and Rust SDK repositories.
Additionally, the PR unifies the display of test outputs - logs, debug
output, and reverts:
- for passing tests, none of the output is shown by default, unless
specified on the CLI.
- for failing tests, all the output is displayed in the "failures"
section.
- because the `__dbg` output is not a log, a dedicated `--dbgs` CLI
argument is added, for all ecal outputs.
- because the output of a revert now shows all available information and
not only the revert code, the `--revert-codes` CLI argument is renamed
to `--reverts`.
Closes#7089.
## Checklist
- [x] I have linked to any relevant issues.
- [x] I have commented my code, particularly in hard-to-understand
areas.
- [ ] I have updated the documentation where relevant (API docs, the
reference, and the Sway book).
- [ ] If my change requires substantial documentation changes, I have
[requested support from the DevRel
team](https://github.com/FuelLabs/devrel-requests/issues/new/choose)
- [x] I have added tests that prove my fix is effective or that my
feature works.
- [ ] I have added (or requested a maintainer to add) the necessary
`Breaking*` or `New Feature` labels where relevant.
- [x] I have done my best to ensure that my PR adheres to [the Fuel Labs
Code Review
Standards](https://github.com/FuelLabs/rfcs/blob/master/text/code-standards/external-contributors.md).
- [x] I have requested a review from the relevant team or maintainers.
## Description
Close#2369
**Summary:**
Implements functionality for `forc` to add remove dependencies through
cli, similar to Cargo's `add` and `remove` commands.
**Work Done:**
* ✅ Added `forc add` command to support adding both regular and contract
dependencies from path, git, IPFS, or version.
* ✅ Implemented conflict checks for version + source collisions (e.g.,
version + git).
* ✅ Added automatic fallback to workspace-relative path for local
packages.
* ✅ Introduced `forc remove` to cleanly remove specified dependencies
from the manifest.
* ✅ Modularized update logic using `DepSection` enum for unified
regular/contract dependency handling.
* ✅ Used `toml_edit` to update the manifest file while preserving
formatting.
## Checklist
- [x] I have linked to any relevant issues.
- [x] I have commented my code, particularly in hard-to-understand
areas.
- [x] I have updated the documentation where relevant (API docs, the
reference, and the Sway book).
- [ ] If my change requires substantial documentation changes, I have
[requested support from the DevRel
team](https://github.com/FuelLabs/devrel-requests/issues/new/choose)
- [x] I have added tests that prove my fix is effective or that my
feature works.
- [x] I have added (or requested a maintainer to add) the necessary
`Breaking*` or `New Feature` labels where relevant.
- [x] I have done my best to ensure that my PR adheres to [the Fuel Labs
Code Review
Standards](https://github.com/FuelLabs/rfcs/blob/master/text/code-standards/external-contributors.md).
- [x] I have requested a review from the relevant team or maintainers.
## Description
This PR removes the double compilation of contract methods in the IR, in
the case of new encoding.
The contract methods were first compiled as a part of the compilation of
the `__entry` function, and afterwards, again separately. The contract
methods compiled in the second compilation pass were later on removed as
not reachable.
The issue was brought to the surface in a test written by @hal3e in
[fuel-rs PR that integrates ABI
errors](https://github.com/FuelLabs/fuels-rs/pull/1651). In that
particular test, because of the double compilation, a `panic` expression
in a contract method got compiled twice and produced two same entries in
the ABI JSON.
Removing the double compilation resulted in a small reduction of
bytecode size and gas usage. In some tests bytecode size got reduced for
~50 bytes and the gas usage for ~30 gas units.
Additionally, the PR adjusts the printing of IR global variables, to be
the same as printing of configurables and locals, without the spaces
between individual entries.
## Checklist
- [ ] I have linked to any relevant issues.
- [x] I have commented my code, particularly in hard-to-understand
areas.
- [ ] I have updated the documentation where relevant (API docs, the
reference, and the Sway book).
- [ ] If my change requires substantial documentation changes, I have
[requested support from the DevRel
team](https://github.com/FuelLabs/devrel-requests/issues/new/choose)
- [ ] I have added tests that prove my fix is effective or that my
feature works.
- [ ] I have added (or requested a maintainer to add) the necessary
`Breaking*` or `New Feature` labels where relevant.
- [x] I have done my best to ensure that my PR adheres to [the Fuel Labs
Code Review
Standards](https://github.com/FuelLabs/rfcs/blob/master/text/code-standards/external-contributors.md).
- [x] I have requested a review from the relevant team or maintainers.
## Description
This PR adds an initial support to symbolic fuel-vm interpretation to
improve codegen. The symbolic execution is designed to be extended in
later PRs. In it's current form, it provides three distinct
improvements:
1. If a temporary (allocated) register contains a value already held in
another register, we can use that other register instead. This reduces
register pressure, and removes unnecessary `mov` ops.
2. If a register already has the value we're setting it to, we can
eliminate the instruction doing so.
3. For conditional jump instructions, if the value of the condition is
known, one of the branches can be elminated. In such cases, the
instruction is either removed or replaced with an unconditional jump.
Dead code elimination pass can then potentially remove the
now-unreachable branch.
In addition to these changes, this PR takes the optimization level into
account for asm generation. For debug builds, we only run the
optimization passes once. But for release builds we run the optimization
passes multiple times, until we either cannot eliminate any more
operations, or until a fixed upper limit of rounds. For instance, this
means that if the new pass added in this PR manages to eliminate a
branch, and then dead code elimination removes that code, it could allow
the interpretation pass to do even more work.
To account for new optimization passes, I also organized them to mulple
files, so that the ones which create private types are scoped well and
thus easier to read.
## Impact
project | size before | size after | size reduction
-|-|-|-
mira-v1-core | 89.384 KB | 83.480 KB | 6.6%
## Checklist
- [x] I have linked to any relevant issues.
- [x] I have commented my code, particularly in hard-to-understand
areas.
- [x] I have updated the documentation where relevant (API docs, the
reference, and the Sway book). No changes required!
- [x] If my change requires substantial documentation changes, I have
[requested support from the DevRel
team](https://github.com/FuelLabs/devrel-requests/issues/new/choose)
- [x] I have added tests that prove my fix is effective or that my
feature works. Just updated pre-existing ones!
- [x] I have added (or requested a maintainer to add) the necessary
`Breaking*` or `New Feature` labels where relevant.
- [x] I have done my best to ensure that my PR adheres to [the Fuel Labs
Code Review
Standards](https://github.com/FuelLabs/rfcs/blob/master/text/code-standards/external-contributors.md).
- [x] I have requested a review from the relevant team or maintainers.
---------
Co-authored-by: Vaivaswatha N <vaivaswatha.nagaraj@fuel.sh>
Co-authored-by: Joshua Batty <joshpbatty@gmail.com>
## Description
This PR introduces the `panic` expression to the language, as defined in
the [ABI Errors
RFC](https://github.com/FuelLabs/sway-rfcs/blob/master/rfcs/0014-abi-errors.md#panic).
The `panic` expression can be used without arguments, or accept an
argument that implements the `std::marker::Error` trait. The `Error`
trait is implemented by the compiler for the unit `()`, string slices,
and `#[error_type]` enums.
Using the `panic` expression without arguments gives the symetry with
the `return` expression and acts in the same way as having unit as an
argument.
```
panic;
panic ();
panic "This is some error.";
panic Errors::SomeError(42);
```
Panicking without an argument or with unit as argument is discouraged to
use. In the upcoming PR that finalizes the ABI errors feature, we will
emit a warning if the `panic` is used without arguments or with unit as
argument.
`panic` expression is available in all program kinds. In predicates it
currently compiles only to revert. Once `__dbg` intrinsic is
implemented, we can consider compiling to it in predicates. In the
upcoming PR, the `error_codes` entry in the ABI JSON will be available
for all program kinds.
The dead code analysis for the `panic` expression is implemented in the
straightforward way, following the current approach of connecting
reverts to the exit node. This will be revisted in a separate PR,
together with the open TODOs in the DCA implementation of `Return`.
Essentially, we want reverting/panicking to connect to program exit and
implicit returns to the exit node.
Additionally, the PR:
- extends `forc test` CLI attributes with `--revert-codes` that prints
revert codes even if tests are successful but revert.
- updates outdated "Logs Inside Tests" chapter in the documentation on
unit testing.
- extends the snapshot testing infrastructure to support `forc test` in
snapshot tests.
- fixes#7072.
Partially addresses #6765.
## Breaking Change
`panic` is a new reserved keyword. Once the `error_type` feature becomes
integrated, compiling any existing code containing a "panic" as an
identifier will result in an "Identifiers cannot be a reserved keyword."
error.
In this PR, `panic` keyword is hidden behind the `error_type` feature
flag. This prevents existing code from breaking, unless opted-in.
Note that, although being behind a feature flag, `panic` cannot be used
in conditional compilation, means in combination with the
`#[cfg(experimental_error_type = true/false)]`. The reason is that `cfg`
evaluation happens after parsing, and we can either parse `panic` as a
keyword or identifier during the parsing, because we cannot distinguish
ambiguous cases like `panic;` or just `panic`.
This limitation means, that introducing `panic` to `std` can be done
only once the `error_type` feature is fully integrated. In practice,
this is not a serious limitation, because introducing `panic` in `std`
would anyhow, due to effort and design decisions, happen after the
feature is integrated.
We will provide a migration for this breaking change that will migrate
the existing "panic" identifiers to "r#panic".
## Checklist
- [x] I have linked to any relevant issues.
- [x] I have commented my code, particularly in hard-to-understand
areas.
- [x] I have updated the documentation where relevant (API docs, the
reference, and the Sway book).
- [ ] If my change requires substantial documentation changes, I have
[requested support from the DevRel
team](https://github.com/FuelLabs/devrel-requests/issues/new/choose)
- [x] I have added tests that prove my fix is effective or that my
feature works.
- [x] I have added (or requested a maintainer to add) the necessary
`Breaking*` or `New Feature` labels where relevant.
- [x] I have done my best to ensure that my PR adheres to [the Fuel Labs
Code Review
Standards](https://github.com/FuelLabs/rfcs/blob/master/text/code-standards/external-contributors.md).
- [x] I have requested a review from the relevant team or maintainers.
## Description
This PR implements the `__dbg(...)` intrinsic, which is very similar to
Rust `dbg!(...)` macro.
Up until now, it has being the norm to use `__log` to debug values.
Given that this is NOT the first use case for log, we have always found
some issues with it: log does not work on predicates, log does not show
"private" fields like `Vec::capacity` and others.
To solve these problems `__dbg` is being introduced:
1 - it will work on all program types, including predicates;
2 - it also prints the file name, line and column;
3 - All types will have an automatic implementation of Debug if
possible, which can still be customized.
4 - Even `raw_ptr` and other non "loggable" types, have `Debug` impls.
5 - `__dbg` will be completely stripped in the release build by default.
It can be turned on again if needed.
So this:
```
// Aggregates
let _ = __dbg((1u64, 2u64));
let _ = __dbg([1u64, 2u64]);
// Structs and Enums
let _ = __dbg(S { });
let _ = __dbg(E::None);
let _ = __dbg(E::Some(S { }));
```
will generate this:
```
[src/main.sw:19:13] = (1, 2)
[src/main.sw:20:13] = [1, 2]
[src/main.sw:23:13] = S { }
[src/main.sw:24:13] = None
[src/main.sw:25:13] = E(S { })
```
How does this work?
`__dbg(value)` intrinsic is desugared into `{ let f = Formatter{};
f.print_str(...); let value = value; value.fmt(f); value }`.
`Formatter` is similar to Rust's one. The difference is that we still do
not support string formatting, so the `Formatter` has a lot of `print_*`
functions.
And each `print` function calls a "syscall". This `syscall` uses `ecal`
under the hood and it follows unix write syscall schema.
```sway
// ssize_t write(int fd, const void buf[.count], size_t count);
fn syscall_write(fd: u64, buf: raw_ptr, count: u64) {
asm(id: 1000, fd: fd, buf: buf, count: count) {
ecal id fd buf count;
}
}
```
For that to work, the VM interpreter must have its `EcalState` setup and
interpret syscall number 1000 as `write`. This PR does this for `forc
test` and our `e2e test suite`.
Each test in `forc test` will capture these calls and only print to the
terminal when requested with the `--log` flag.
## Garbage Collector and auto generated
Before, we were associating all auto-generated code with a pseudo file
called "<autogenerated>.sw" that was never garbage collected.
This generated a problem inside the LSP when the `auto_impl.rs` ran a
second time because of a collision in the "shareable type" map. When we
try to solve this collision, choosing to keep the old value or to insert
the new, the type inside the map points to already collected types and
the compiler panics. This is a known problem.
The workaround for this is to break the auto-generated code into
multiple files. Now they are named "main.autogenerated.sw", for example.
We create one pseudo-file for each real file that needs one.
When we garbage collect one file, `main.sw`, for example, we also
collect its associated auto-generated file.
## Checklist
- [ ] I have linked to any relevant issues.
- [x] I have commented my code, particularly in hard-to-understand
areas.
- [x] I have updated the documentation where relevant (API docs, the
reference, and the Sway book).
- [ ] If my change requires substantial documentation changes, I have
[requested support from the DevRel
team](https://github.com/FuelLabs/devrel-requests/issues/new/choose)
- [x] I have added tests that prove my fix is effective or that my
feature works.
- [ ] I have added (or requested a maintainer to add) the necessary
`Breaking*` or `New Feature` labels where relevant.
- [x] I have done my best to ensure that my PR adheres to [the Fuel Labs
Code Review
Standards](https://github.com/FuelLabs/rfcs/blob/master/text/code-standards/external-contributors.md).
- [x] I have requested a review from the relevant team or maintainers.
## Description
This PR is a prequel to https://github.com/FuelLabs/sway/pull/7015,
trying to optimize the compiler to alleviate the hit of having more
items, `impl` etc...
We have here two optimizations:
1 - We spend a lot of time counting newlines when converting byte
offsets to `LineCol`. Now, we calculate line offsets just once, and use
binary search later to find which line a byte offset is at.
2 - `QueryEngine::get_programs_cache_entry` was cloning the whole
`TyProgram`. That is why `did_change_with_caching` was always getting
worse, as the program was increasing in size. Now all compilation stages
are behind `Arc`, which makes the `clone` free.
## Analysis
Putting a `dbg!(...)` like the image below, and calling `counts`
(https://github.com/nnethercote/counts).
```
cargo bench -- traverse 2>&1 | grep "sway-types/src/span.rs:29:9" | counts
```

I get the following results:
```
972102 counts
( 1) 156720 (16.1%, 16.1%): [sway-types/src/span.rs:29:9] self.pos = 0
( 2) 15900 ( 1.6%, 17.8%): [sway-types/src/span.rs:29:9] self.pos = 104
( 3) 15840 ( 1.6%, 19.4%): [sway-types/src/span.rs:29:9] self.pos = 107
( 4) 2280 ( 0.2%, 19.6%): [sway-types/src/span.rs:29:9] self.pos = 19281
( 5) 2280 ( 0.2%, 19.9%): [sway-types/src/span.rs:29:9] self.pos = 19285
( 6) 2280 ( 0.2%, 20.1%): [sway-types/src/span.rs:29:9] self.pos = 19287
( 7) 2280 ( 0.2%, 20.3%): [sway-types/src/span.rs:29:9] self.pos = 19292
( 8) 2280 ( 0.2%, 20.6%): [sway-types/src/span.rs:29:9] self.pos = 19323
( 9) 2280 ( 0.2%, 20.8%): [sway-types/src/span.rs:29:9] self.pos = 19327
( 10) 2280 ( 0.2%, 21.0%): [sway-types/src/span.rs:29:9] self.pos = 19329
( 11) 2280 ( 0.2%, 21.3%): [sway-types/src/span.rs:29:9] self.pos = 19334
( 12) 870 ( 0.1%, 21.4%): [sway-types/src/span.rs:29:9] self.pos = 4285
...
```
This means that `line_col` is being called 972k times. 16% is for
position zero, which should be trivial. The rest will iterate the whole
file source code to count number of lines. Making the real complexity of
the work here something like `O(qty * self.pos)`. And some values of
`self.pos` are not trivial at all.
## Checklist
- [ ] I have linked to any relevant issues.
- [ ] I have commented my code, particularly in hard-to-understand
areas.
- [ ] I have updated the documentation where relevant (API docs, the
reference, and the Sway book).
- [ ] If my change requires substantial documentation changes, I have
[requested support from the DevRel
team](https://github.com/FuelLabs/devrel-requests/issues/new/choose)
- [ ] I have added tests that prove my fix is effective or that my
feature works.
- [ ] I have added (or requested a maintainer to add) the necessary
`Breaking*` or `New Feature` labels where relevant.
- [ ] I have done my best to ensure that my PR adheres to [the Fuel Labs
Code Review
Standards](https://github.com/FuelLabs/rfcs/blob/master/text/code-standards/external-contributors.md).
- [ ] I have requested a review from the relevant team or maintainers.
close#5017
PR adds new `--generate-hexfile` flag to the `forc build` command,
enabling it to output a hex-encoded JSON representation of the compiled
binary alongside the `.bin` file.
#### ✅ Changes
- Added `--generate-hexfile` flag to `forc build`.
- Outputs a `.json` file containing the hex-encoded script binary (e.g.,
`contract-hex.json`).
- Ensures bundler compatibility for frontend/SDK consumption.
#### 🧪 Example Output
```json
{
"hex": "0xdeadbeefcafebabe..."
}
```
#### 📦 Example Usage
```bash
forc build --generate-hexfile
```
Generates:
- `contract.bin` (as before)
- `contract-hex.json` (new hex representation)
## Checklist
- [x] I have linked to any relevant issues.
- [x] I have commented my code, particularly in hard-to-understand
areas.
- [ ] I have updated the documentation where relevant (API docs, the
reference, and the Sway book).
- [ ] If my change requires substantial documentation changes, I have
[requested support from the DevRel
team](https://github.com/FuelLabs/devrel-requests/issues/new/choose)
- [ ] I have added tests that prove my fix is effective or that my
feature works.
- [ ] I have added (or requested a maintainer to add) the necessary
`Breaking*` or `New Feature` labels where relevant.
- [x] I have done my best to ensure that my PR adheres to [the Fuel Labs
Code Review
Standards](https://github.com/FuelLabs/rfcs/blob/master/text/code-standards/external-contributors.md).
- [x] I have requested a review from the relevant team or maintainers.
---------
Co-authored-by: Sophie Dankel <47993817+sdankel@users.noreply.github.com>
Co-authored-by: zees-dev <63374656+zees-dev@users.noreply.github.com>
Co-authored-by: Joshua Batty <joshpbatty@gmail.com>
## Description
Merges the two libraries. They were initially separate to separate the
core logic and fuel vm specific functionality, but that separation is no
longer maintained so having a merged library is better.
Closes#6708
## Checklist
- [ ] I have linked to any relevant issues.
- [ ] I have commented my code, particularly in hard-to-understand
areas.
- [ ] I have updated the documentation where relevant (API docs, the
reference, and the Sway book).
- [ ] If my change requires substantial documentation changes, I have
[requested support from the DevRel
team](https://github.com/FuelLabs/devrel-requests/issues/new/choose)
- [ ] I have added tests that prove my fix is effective or that my
feature works.
- [ ] I have added (or requested a maintainer to add) the necessary
`Breaking*` or `New Feature` labels where relevant.
- [ ] I have done my best to ensure that my PR adheres to [the Fuel Labs
Code Review
Standards](https://github.com/FuelLabs/rfcs/blob/master/text/code-standards/external-contributors.md).
- [ ] I have requested a review from the relevant team or maintainers.
---------
Co-authored-by: Sophie <47993817+sdankel@users.noreply.github.com>
Co-authored-by: Igor Rončević <ironcev@hotmail.com>
## Description
- Added support for viewing emitted logs when making a transaction using
forc-call
- Added `show_receipts` param (default-false) - so we can optionally
prnt out all receipts
- The CLI output becomes too long for a call with multiple receipts;
this is a minor UI enhancement
Addresses https://github.com/FuelLabs/sway/issues/6887
## Example usage/output
```sway
script;
struct ExampleParams {
test_val: u32,
test_str: str,
test_tuple: (u32, u64),
}
fn main() -> u64 {
log("hiiii");
log(123);
log(ExampleParams { test_val: 5, test_str: "hello world", test_tuple: (1,2) });
5
}
```
<img width="986" alt="image"
src="https://github.com/user-attachments/assets/3725ff17-29c9-43d7-98cc-4cacfc213ecb"
/>
## Checklist
- [x] I have linked to any relevant issues.
- [x] I have commented my code, particularly in hard-to-understand
areas.
- [ ] I have updated the documentation where relevant (API docs, the
reference, and the Sway book).
- [x] If my change requires substantial documentation changes, I have
[requested support from the DevRel
team](https://github.com/FuelLabs/devrel-requests/issues/new/choose)
- [ ] I have added tests that prove my fix is effective or that my
feature works.
- [ ] I have added (or requested a maintainer to add) the necessary
`Breaking*` or `New Feature` labels where relevant.
- [ ] I have done my best to ensure that my PR adheres to [the Fuel Labs
Code Review
Standards](https://github.com/FuelLabs/rfcs/blob/master/text/code-standards/external-contributors.md).
- [ ] I have requested a review from the relevant team or maintainers.
---------
Co-authored-by: z <zees-dev@users.noreply.github.com>
Co-authored-by: Joshua Batty <joshpbatty@gmail.com>
Co-authored-by: kayagokalp <kayagokalp123@gmail.com>
## Description
Moves dev dependencies to the workspace Cargo.toml for consistent
versions in tests.
Inspired by https://github.com/FuelLabs/sway/pull/6955
## Checklist
- [ ] I have linked to any relevant issues.
- [ ] I have commented my code, particularly in hard-to-understand
areas.
- [ ] I have updated the documentation where relevant (API docs, the
reference, and the Sway book).
- [ ] If my change requires substantial documentation changes, I have
[requested support from the DevRel
team](https://github.com/FuelLabs/devrel-requests/issues/new/choose)
- [ ] I have added tests that prove my fix is effective or that my
feature works.
- [ ] I have added (or requested a maintainer to add) the necessary
`Breaking*` or `New Feature` labels where relevant.
- [ ] I have done my best to ensure that my PR adheres to [the Fuel Labs
Code Review
Standards](https://github.com/FuelLabs/rfcs/blob/master/text/code-standards/external-contributors.md).
- [ ] I have requested a review from the relevant team or maintainers.
## Description
SIgnificantly reduces bytecode sizes by transforming the following
commonly-used operations when the constant value fits into the immediate
part of the `*i` variant of the instruction:
* `MOVI(tmp, copy_len); MCP(dst, src, tmp)` → `MCPI(dst, src, copy_len)`
(in `compile_mem_copy_bytes`)
* `MOVI(dst, offset); ADD(dst, dst, DATA_SECTION)` → `ADDI(dst,
DATA_SECTION, offset)` (in `addr_of`)
## Checklist
- [ ] I have linked to any relevant issues. (none that I know of)
- [x] I have commented my code, particularly in hard-to-understand
areas.
- [ ] I have updated the documentation where relevant (API docs, the
reference, and the Sway book). (no changes required)
- [ ] If my change requires substantial documentation changes, I have
[requested support from the DevRel
team](https://github.com/FuelLabs/devrel-requests/issues/new/choose)
- [ ] I have added tests that prove my fix is effective or that my
feature works. (partially; some values in tests got smaller. we don't
seem to be tracking the size and size regressions in tests)
- [x] I have added (or requested a maintainer to add) the necessary
`Breaking*` or `New Feature` labels where relevant. (not relevant)
- [x] I have done my best to ensure that my PR adheres to [the Fuel Labs
Code Review
Standards](https://github.com/FuelLabs/rfcs/blob/master/text/code-standards/external-contributors.md).
- [x] I have requested a review from the relevant team or maintainers.
## Description
Depends on https://github.com/FuelLabs/sway/pull/6522
Related https://github.com/FuelLabs/forc.pub/issues/16
Adds a function, `get_bytecode_id` that generates a sha256 hash of the
bytecode with the configurables section of the bytecode removed. This
will be used for indexing and lookups of the corresponding ABIs for
contracts, predicates, and scripts in the package registry (forc.pub).
## Checklist
- [ ] I have linked to any relevant issues.
- [ ] I have commented my code, particularly in hard-to-understand
areas.
- [ ] I have updated the documentation where relevant (API docs, the
reference, and the Sway book).
- [ ] If my change requires substantial documentation changes, I have
[requested support from the DevRel
team](https://github.com/FuelLabs/devrel-requests/issues/new/choose)
- [ ] I have added tests that prove my fix is effective or that my
feature works.
- [ ] I have added (or requested a maintainer to add) the necessary
`Breaking*` or `New Feature` labels where relevant.
- [ ] I have done my best to ensure that my PR adheres to [the Fuel Labs
Code Review
Standards](https://github.com/FuelLabs/rfcs/blob/master/text/code-standards/external-contributors.md).
- [ ] I have requested a review from the relevant team or maintainers.
---------
Co-authored-by: Vaivaswatha Nagaraj <vaivaswatha.nagaraj@fuel.sh>
Co-authored-by: IGI-111 <igi-111@protonmail.com>
Co-authored-by: Marcos Henrich <marcoshenrich@gmail.com>
Co-authored-by: Joshua Batty <joshpbatty@gmail.com>
Re-enabling this feature after a bugfix. (reverted PR: #6522)
---------
Co-authored-by: Sophie Dankel <47993817+sdankel@users.noreply.github.com>
Co-authored-by: IGI-111 <igi-111@protonmail.com>
## Description
This pull request adds the profile feature in the Sway compiler.
It communicates with an external `forc-perf` executable in order to
signal the beginning and end of different compilation phases for
profiling purposes.
(re-opening of https://github.com/FuelLabs/sway/pull/6565)
## Checklist
- [x] I have linked to any relevant issues.
- [x] I have commented my code, particularly in hard-to-understand
areas.
- [x] I have updated the documentation where relevant (API docs, the
reference, and the Sway book).
- [x] If my change requires substantial documentation changes, I have
[requested support from the DevRel
team](https://github.com/FuelLabs/devrel-requests/issues/new/choose)
- [x] I have added tests that prove my fix is effective or that my
feature works.
- [x] I have added (or requested a maintainer to add) the necessary
`Breaking*` or `New Feature` labels where relevant.
- [x] I have done my best to ensure that my PR adheres to [the Fuel Labs
Code Review
Standards](https://github.com/FuelLabs/rfcs/blob/master/text/code-standards/external-contributors.md).
- [x] I have requested a review from the relevant team or maintainers.
---------
Co-authored-by: Camden Smallwood <camden.smallwood@gmail.com>
Co-authored-by: GeorgiosDelkos <georgios.delkos@ourovoros.io>
Co-authored-by: IGI-111 <igi-111@protonmail.com>
## Description
related to #2601.
Removes ansi_term dependency from sway crates. To remove the dependency
completely from dep tree we need a release of sway repo to get a new
version of forc_util and use it in forc_wallet as forc_wallet is
depending on `forc-util v0.47.0` which uses `ansi_term`. Once that is
done we can close#2601
The preamble now contains 8 bytes of offset to the configurables
section. If there is no configurable const in the data-section, then the
value of this integer will be equal to the size of the binary itself.
This also means that we now sort the data-section to have all the
non-configurables first, and then the configurables.
The preamble final asm looks like this (the offset to configurables is
0'd out here in the example):
```
;; ASM: Final program
;; Program kind: Script
.program:
move $$tmp $pc
jmpf $zero i10
DATA_SECTION_OFFSET[0..32]
DATA_SECTION_OFFSET[32..64]
CONFIGURABLES_OFFSET[0..32]
CONFIGURABLES_OFFSET[32..64]
lw $$ds $$tmp i1
add $$ds $$ds $$tmp
```
The preamble bytecode looks like this:
```
0x00000000 MOVE R60 $pc ;; [26, 240, 48, 0]
0x00000004 JMPF $zero 0xa ;; [116, 0, 0, 10]
0x00000008 ;; [0, 0, 0, 0, 0, 0, 2, 40]
0x00000010 ;; [0, 0, 0, 0, 0, 0, 0, 0]
0x00000030 LW R63 R60 0x1 ;; [93, 255, 192, 1]
0x00000034 ADD R63 R63 R60 ;; [16, 255, 255, 0]
...
```
---------
Co-authored-by: Sophie Dankel <47993817+sdankel@users.noreply.github.com>
Co-authored-by: IGI-111 <igi-111@protonmail.com>
## Description
This PR starts the implementation of
https://github.com/FuelLabs/sway-rfcs/blob/master/rfcs/0013-changes-lifecycle.md.
## CLI flags
Now, all `CLI`s, including our tests, support two new arguments
```
...
--experimental <EXPERIMENTAL>
Comma separated list of all experimental features that will be enabled [possible values: new_encoding, storage_domains]
--no-experimental <NO_EXPERIMENTAL>
Comma separated list of all experimental features that will be disabled [possible values: new_encoding, storage_domains]
...
```
Experimental features can also be enabled inside `Forc.toml` for
workspaces and individual projects.
```
experimental = { encoding-v1 = true }
```
And can be enabled using environment variables:
```
FORC_NO_EXPERIMENTAL=feature_a,feature_b FORC_EXPERIMENTAL=feature_c forc build ...
```
These configurations are applied in a very specific order to allow them
to be overwritten. The order from the weakest to the strongest is:
1 - Workspace `TOML`
2 - Project `TOML`
3 - CLI
4 - Environment variables.
The rationale is:
1 - We want an easy way to enable and/or disable a feature for the whole
workspace;
2 - But we want to allow projects to overwrite these features, when
needed.
These two are the suggested approach to configure experimental features,
but we also want to allow someone to easily turn on or off features to
test something in particular. For that one can use the CLI flags; and in
the specific case one does not have access to the CLI, for example, when
one of the `SDK` is compiling the code, one can still completely
overwrite the `TOML` files using environment variables.
We are also applying the "no experimental" first. This is to allow the
use case of exactly controlling which features will be enabled and
disabled. In this case one can use the "meta-feature" `all` to disable
everything and enable only the desired features. For example:
```
FORC_NO_EXPERIMENTAL=all FORC_EXPERIMENTAL=new_encoding your_command....
```
## Test for "-h"
This PR also introduces snapshot tests for "-h" for all forc commands at
https://github.com/FuelLabs/sway/pull/6586/files#diff-20a5e677d2ae9266a2247739b6a473d2ad0c627955187d668822e7d194f8e940
## Multiple test.toml
This PR also enables the use of multiple `test.toml`. Now each
`test.toml` will be a different test, allowing the same code to be
compiled and asserted differently.
For example, `main_args_empty` has two files: the normal `test.toml` and
a new `test.encoding_v1.toml`. One has `new_encoding` enabled and the
other disabled.
When a `test.toml` file has the `experimental` field, we do not use
fields with `_new_encoding` suffix anymore, making these files simpler:
test.toml:
```toml
category = "run"
# (1336, 1)
script_data = "0000000000000538 0000000000000001"
expected_result = { action = "return", value = 1337 }
validate_abi = true
experimental = { encoding_v1 = false }
```
test.encoding_v1.toml
```
script_data = "0000000000000538 0000000000000001"
expected_result = { action = "return_data", value = "0000000000000539" }
experimental = { new_encoding = true }
```
Test tomls with a suffix use `test.toml` as a base. So we do not need to
repeat every field in them.
Now when we run a test, we will see two tests instead of just one:
```
...
Testing should_pass/language/main_args/main_args_empty (test.encoding_v1.toml) ... ok
Testing should_pass/language/main_args/main_args_empty (test.toml) ... ok
...
```
## Conditional compilation
It is also possible to use conditional compilation using these
experimental features. Examples can be found inside `sway-lib-std`.
```sway
#[cfg(experimental_new_encoding = true)]
pub fn assert_eq<T>(v1: T, v2: T) {
...
}
```
## Checklist
- [ ] I have linked to any relevant issues.
- [ ] I have commented my code, particularly in hard-to-understand
areas.
- [ ] I have updated the documentation where relevant (API docs, the
reference, and the Sway book).
- [ ] If my change requires substantial documentation changes, I have
[requested support from the DevRel
team](https://github.com/FuelLabs/devrel-requests/issues/new/choose)
- [ ] I have added tests that prove my fix is effective or that my
feature works.
- [ ] I have added (or requested a maintainer to add) the necessary
`Breaking*` or `New Feature` labels where relevant.
- [ ] I have done my best to ensure that my PR adheres to [the Fuel Labs
Code Review
Standards](https://github.com/FuelLabs/rfcs/blob/master/text/code-standards/external-contributors.md).
- [ ] I have requested a review from the relevant team or maintainers.
---------
Co-authored-by: IGI-111 <igi-111@protonmail.com>
## Description
As part of #6179, this PR updates the remaining quick-fix crates to
their latest X.Y versions. Code fixes were needed to get compilation
working and tests passing.
Issue #6536 lists the crates that will need a bit more work to get
working and passing.
## Checklist
- [x] I have linked to any relevant issues.
- [x] I have commented my code, particularly in hard-to-understand
areas.
- [x] I have updated the documentation where relevant (API docs, the
reference, and the Sway book).
- [x] If my change requires substantial documentation changes, I have
[requested support from the DevRel
team](https://github.com/FuelLabs/devrel-requests/issues/new/choose)
- [x] I have added tests that prove my fix is effective or that my
feature works.
- [x] I have added (or requested a maintainer to add) the necessary
`Breaking*` or `New Feature` labels where relevant.
- [x] I have done my best to ensure that my PR adheres to [the Fuel Labs
Code Review
Standards](https://github.com/FuelLabs/rfcs/blob/master/text/code-standards/external-contributors.md).
- [x] I have requested a review from the relevant team or maintainers.
## Description
For #6179, PR #6501 kept bumping into errors as it was doing too many
things, so I've split that PR into multiple PRs. This is the first, and
the only thing it does is move all of the various `Cargo.toml`
dependencies into the single workspace `Cargo.toml`.
Future PRs will:
- Update dependency versions
- Update code that breaks from the version bumps
## Checklist
- [x] I have linked to any relevant issues.
- [x] I have commented my code, particularly in hard-to-understand
areas.
- [x] I have updated the documentation where relevant (API docs, the
reference, and the Sway book).
- [x] If my change requires substantial documentation changes, I have
[requested support from the DevRel
team](https://github.com/FuelLabs/devrel-requests/issues/new/choose)
- [x] I have added tests that prove my fix is effective or that my
feature works.
- [x] I have added (or requested a maintainer to add) the necessary
`Breaking*` or `New Feature` labels where relevant.
- [x] I have done my best to ensure that my PR adheres to [the Fuel Labs
Code Review
Standards](https://github.com/FuelLabs/rfcs/blob/master/text/code-standards/external-contributors.md).
- [x] I have requested a review from the relevant team or maintainers.
## Description
Closes https://github.com/FuelLabs/sway/issues/6015
- Adds the `--raw-logs` option
- Removes the `decode` option as this is now the default for `--logs`
- Shortens `--pretty-print` to `--pretty`
## Checklist
- [x] I have linked to any relevant issues.
- [ ] I have commented my code, particularly in hard-to-understand
areas.
- [ ] I have updated the documentation where relevant (API docs, the
reference, and the Sway book).
- [ ] If my change requires substantial documentation changes, I have
[requested support from the DevRel
team](https://github.com/FuelLabs/devrel-requests/issues/new/choose)
- [x] I have added tests that prove my fix is effective or that my
feature works.
- [ ] I have added (or requested a maintainer to add) the necessary
`Breaking*` or `New Feature` labels where relevant.
- [ ] I have done my best to ensure that my PR adheres to [the Fuel Labs
Code Review
Standards](https://github.com/FuelLabs/rfcs/blob/master/text/code-standards/external-contributors.md).
- [x] I have requested a review from the relevant team or maintainers.
## Description
To be merged after https://github.com/FuelLabs/sway/pull/6250
## Checklist
- [ ] I have linked to any relevant issues.
- [ ] I have commented my code, particularly in hard-to-understand
areas.
- [ ] I have updated the documentation where relevant (API docs, the
reference, and the Sway book).
- [ ] If my change requires substantial documentation changes, I have
[requested support from the DevRel
team](https://github.com/FuelLabs/devrel-requests/issues/new/choose)
- [ ] I have added tests that prove my fix is effective or that my
feature works.
- [ ] I have added (or requested a maintainer to add) the necessary
`Breaking*` or `New Feature` labels where relevant.
- [ ] I have done my best to ensure that my PR adheres to [the Fuel Labs
Code Review
Standards](https://github.com/FuelLabs/rfcs/blob/master/text/code-standards/external-contributors.md).
- [ ] I have requested a review from the relevant team or maintainers.
---------
Co-authored-by: Brandon Kite <brandonkite92@gmail.com>
Co-authored-by: IGI-111 <igi-111@protonmail.com>
## Description
Updates all the dependencies for the current release.
Implements the fuel ABI generation changes proposed in
https://github.com/FuelLabs/fuel-specs/pull/599.
Removes the flag `--json-abi-with-callpaths` and the behavior is as if
it were true. We removed the flag because it is unsafe to produce JSON
ABIs without callpaths, so we shouldn't allow it.
Includes the LDC, BSIZ, BLDD and ED19 changes
from:https://github.com/FuelLabs/sway/pull/6409.
Fixes https://github.com/FuelLabs/sway/issues/5954
Fixes https://github.com/FuelLabs/sway/issues/5151
## Checklist
- [x] I have linked to any relevant issues.
- [x] I have commented my code, particularly in hard-to-understand
areas.
- [ ] I have updated the documentation where relevant (API docs, the
reference, and the Sway book).
- [ ] If my change requires substantial documentation changes, I have
[requested support from the DevRel
team](https://github.com/FuelLabs/devrel-requests/issues/new/choose)
- [x] I have added tests that prove my fix is effective or that my
feature works.
- [x] I have added (or requested a maintainer to add) the necessary
`Breaking*` or `New Feature` labels where relevant.
- [x] I have done my best to ensure that my PR adheres to [the Fuel Labs
Code Review
Standards](https://github.com/FuelLabs/rfcs/blob/master/text/code-standards/external-contributors.md).
- [x] I have requested a review from the relevant team or maintainers.
---------
Co-authored-by: Vaivaswatha Nagaraj <vaivaswatha.nagaraj@fuel.sh>
Co-authored-by: Kaya Gokalp <kayagokalp123@gmail.com>
Co-authored-by: Kaya Gökalp <kaya.gokalp@fuel.sh>
Co-authored-by: Igor Rončević <ironcev@hotmail.com>
Co-authored-by: IGI-111 <igi-111@protonmail.com>
Co-authored-by: Sophie Dankel <47993817+sdankel@users.noreply.github.com>
## Description
This adds a couple new flags to the test runner which allow filtering
the tests to exclude them if they contain a dependency on either `core`
or `std`.
This is useful to debug issues, since it allows to run tests without any
dependencies, making debugging a bit less difficult when dealing with
complicated issues.
There is also a minor refactoring to `BuildPlan::from_build_opts` which
I thought was necessary, but ended up not being used, but I think doesnt
hurt to keep.
## Checklist
- [ ] I have linked to any relevant issues.
- [ ] I have commented my code, particularly in hard-to-understand
areas.
- [ ] I have updated the documentation where relevant (API docs, the
reference, and the Sway book).
- [ ] If my change requires substantial documentation changes, I have
[requested support from the DevRel
team](https://github.com/FuelLabs/devrel-requests/issues/new/choose)
- [ ] I have added tests that prove my fix is effective or that my
feature works.
- [x] I have added (or requested a maintainer to add) the necessary
`Breaking*` or `New Feature` labels where relevant.
- [x] I have done my best to ensure that my PR adheres to [the Fuel Labs
Code Review
Standards](https://github.com/FuelLabs/rfcs/blob/master/text/code-standards/external-contributors.md).
- [x] I have requested a review from the relevant team or maintainers.
## Description
This PR implements `match` for string slices including radix trie
optimization and is a task of
https://github.com/FuelLabs/sway/issues/5110.
For example a simple `match` like
```
fn return_match_on_str_slice(param: str) -> u64 {
match param {
"get_a" => { 1u64 },
"get_a_b" => { 2u64 },
"get_b" => { 3u64 },
_ => { 1000u64 },
}
}
```
will generate code following this logic:
```
let packed_string = "get_a_b"
if str.len() == 5
if str[0..4] == "get_" at packed_string[0]
if str[4..5] == "b" at packed_string[6]
return branch 2
if str[4..5] == "a" at packed_string[4]
return branch 0
return wildcard branch
return wildcard branch
if str.len() == 7
if str[0..7] == "get_a_b" at packed_string[0]
return branch 1
return wildcard branch
return wildcard branch
```
In logical terms, this boils down to checking the length and an `O(N)`
check on the string. Albeit the bytecode will be more complex because of
all the branches.
Another interesting optimization is the "packed string literal" that
coalesces all "match arms string slices" into just one string. In the
case above, given that one of the arms contains all the necessary
strings for all other comparisons, we will create just one string
literal. Saving a lot of bytes in the data section.
The section below describes how `rustc` deals with this desugaring. I
think these choices make more sense to us for two reasons:
1 - Avoid testing common prefixes multiple times will spend less gas in
general (needs more testing);
2 - packing all strings will decrease the data section size.
This is the bytecode generated in this case:
```
fn return_match_on_str_slice(param: str) -> u64 {
match param {
"get_a" => { 1u64 },
"get_a_b" => { 2u64 },
"get_b" => { 3u64 },
_ => { 1000u64 },
}
} @ /home/xunilrj/github/sway/test/src/e2e_vm_tests/test_programs/should_pass/language/match_expressions_all/src/main.sw:22:1
0x0000017c PSHL 0xf ;; [149, 0, 0, 15]
0x00000180 PSHH 0x80000 ;; [150, 8, 0, 0]
0x00000184 MOVE R59 $sp ;; [26, 236, 80, 0]
0x00000188 CFEI 0x90 ;; [145, 0, 0, 144]
0x0000018c MOVE $writable R58 ;; [26, 67, 160, 0]
0x00000190 MOVE R19 R62 ;; [26, 79, 224, 0]
match param {
"get_a" => { 1u64 },
"get_a_b" => { 2u64 },
"get_b" => { 3u64 },
_ => { 1000u64 },
} @ /home/xunilrj/github/sway/test/src/e2e_vm_tests/test_programs/should_pass/language/match_expressions_all/src/main.sw:23:5
0x00000194 ADDI R17 R59 0x80 ;;
0x00000198 MOVI R18 0x10 ;;
0x0000019c MCP R17 $writable R18 ;;
0x000001a0 MOVI R17 0x7 ;; 0x7 = "get_a_b".len()
@ <autogenerated>:1:1
0x000001a4 LW $writable R59 0x11 ;; R59 + 0x11 = a.len()
0x000001a8 EQ $writable $writable R17 ;; a.len() == 0x7
0x000001ac JNZF $writable $zero 0x3c ;; if false jump to 2a0?
0x000001b0 MOVI R17 0x5 ;; we have two arms with length equals 0x5
0x000001b4 LW $writable R59 0x11 ;; R59 + 0x11 = a.len()
0x000001b8 EQ $writable $writable R17 ;; a.len() == 0x5
0x000001bc MOVI R17 0x3e8 ;; 0x3e8 = 1000 (wildcard return value)
0x000001c0 JNZF $writable $zero 0x1 ;; if true jump to 1c8
0x000001c4 JMPF $zero 0x35 ;; if false jump to 29c (will return R17)
0x000001c8 LW $writable R63 0x3 ;; R63 = start of data section, will load 13c
0x000001cc ADD $writable $writable $pc ;; $writable = 0x308 = packed strings
0x000001d0 ADDI R17 R59 0x20 ;;
0x000001d4 SW R59 $writable 0x4 ;; R59 + 0x4 = packed strings
0x000001d8 MOVI $writable 0x7 ;;
0x000001dc SW R59 $writable 0x5 ;; R59 + 0x5 = 0x7
0x000001e0 ADDI $writable R59 0x30 ;;
0x000001e4 MOVI R18 0x10 ;;
0x000001e8 MCP $writable R17 R18 ;; R59 + 0x30 = R59 + 0x20
0x000001ec MOVI R18 0x4 ;; 0x4 = "get_".len()
0x000001f0 LW $writable R59 0x10 ;;
0x000001f4 ADDI $writable $writable 0x0 ;;
0x000001f8 LW R17 R59 0x6 ;; R17 = a.ptr()
0x000001fc ADDI R17 R17 0x0 ;;
0x00000200 MEQ $writable $writable R17 R18 ;; a[0..4] = packed[0..4]
0x00000204 MOVI R17 0x3e8 ;; 0x3e8 = 1000 (wildcard return value)
0x00000208 JNZF $writable $zero 0x1 ;; if true jump to 210
0x0000020c JMPF $zero 0x23 ;; if false jump to 29c (will return R17)
....
.data_section:
0x00000300 .bytes as hex ([]), len i0, as ascii ""
0x00000300 .word i18446744073709486084, as hex be bytes ([FF, FF, FF, FF, FF, FF, 00, 04])
0x00000308 .bytes as hex ([67, 65, 74, 5F, 61, 5F, 62]), len i7, as ascii "get_a_b"
0x00000310 .word i500, as hex be bytes ([00, 00, 00, 00, 00, 00, 01, F4])
0x00000318 .word i316, as hex be bytes ([00, 00, 00, 00, 00, 00, 01, 3C])
0x00000320 .word i244, as hex be bytes ([00, 00, 00, 00, 00, 00, 00, F4])
0x00000328 .word i176, as hex be bytes ([00, 00, 00, 00, 00, 00, 00, B0])
0x00000330 .word i100, as hex be bytes ([00, 00, 00, 00, 00, 00, 00, 64])
```
## How `rustc` desugar `match`
For comparison, this is the generated ASM with comments on how Rust
tackles this.
First, this is the function used:
```
#[inline(never)]
fn f(a: &str) -> u64 {
match a {
"get_method" => 0,
"get_tokens" => 1,
"get_something_else" => 2,
"get_tokens_2" => 3,
"clear" => 4,
"get_m" => 5,
_ => 6,
}
}
```
This is the LLVM IR generated. There is a match on the length of each
string slice arms. The valid range is (5, 18), everything outside of
this is the wildcard match arm. This range will be important later.
```
efine internal fastcc noundef i64 @example::f::hdb860bcd6d383112(ptr noalias nocapture noundef nonnull readonly align 1 %a.0, i64 noundef %a.1) unnamed_addr {
start:
switch i64 %a.1, label %bb13 [
i64 10, label %"_ZN73_$LT$$u5b$A$u5d$$u20$as$u20$core..slice..cmp..SlicePartialEq$LT$B$GT$$GT$5equal17h510120b4d3581de7E.exit"
i64 18, label %"_ZN73_$LT$$u5b$A$u5d$$u20$as$u20$core..slice..cmp..SlicePartialEq$LT$B$GT$$GT$5equal17h510120b4d3581de7E.exit30"
i64 12, label %"_ZN73_$LT$$u5b$A$u5d$$u20$as$u20$core..slice..cmp..SlicePartialEq$LT$B$GT$$GT$5equal17h510120b4d3581de7E.exit35"
i64 5, label %"_ZN73_$LT$$u5b$A$u5d$$u20$as$u20$core..slice..cmp..SlicePartialEq$LT$B$GT$$GT$5equal17h510120b4d3581de7E.exit40"
]
```
this is how "f" is called
```
mov rbx, qword ptr [rsp + 32]
mov r14, qword ptr [rsp + 40]
mov rsi, qword ptr [rsp + 48] <- length of the string slice
mov rdi, r14 <- ptr to string slice
call _ZN4main1f17h126a5dfd4e318ebcE
```
this is `f` body.
`ja .LBB8_12` jumps into a simple return, returning EAX as 6. It is the
wildcard return value. The cleverness of this is that when `RSI` is
smaller than 5, it will become negative (because of `add rsi, -5`,
wrapping into huge unsigned ints, and will also trigger `JA` (which
stands for `Jump Above`), effectively jumping when the slice length is
outside of the expected range which is (5, 18).
After that, it uses a jump table based on the string length minus 5.
Everywhere the string length is invalid, the jump address is `LBB8_12`.,
still returning `EAX` as 6.
```
_ZN4main1f17h126a5dfd4e318ebcE:
.cfi_startproc
mov eax, 6
add rsi, -5
cmp rsi, 13
ja .LBB8_12
lea rcx, [rip + .LJTI8_0]
movsxd rdx, dword ptr [rcx + 4*rsi]
add rdx, rcx
jmp rdx
```
```
.LBB8_12:
ret
```
This is the jump table used:
```
.LJTI8_0:
.long .LBB8_9-.LJTI8_0
.long .LBB8_12-.LJTI8_0
.long .LBB8_12-.LJTI8_0
.long .LBB8_12-.LJTI8_0
.long .LBB8_12-.LJTI8_0
.long .LBB8_2-.LJTI8_0 <- 5th entry is length = 10 (remember we add -5 to the length)
.long .LBB8_12-.LJTI8_0
.long .LBB8_8-.LJTI8_0
.long .LBB8_12-.LJTI8_0
.long .LBB8_12-.LJTI8_0
.long .LBB8_12-.LJTI8_0
.long .LBB8_12-.LJTI8_0
.long .LBB8_12-.LJTI8_0
.long .LBB8_6-.LJTI8_0
```
The interesting entry is entry 5, which has two strings: "get_method"
and "get_tokens". Here we can see that `rust` actually compares the
complete string slice twice. Even though they have an intersection.
```
.LBB8_2:
movabs rcx, 7526752397670245735=6874656D5F746567="htem_teg" (inverted "get_meth")
xor rcx, qword ptr [rdi]
movzx edx, word ptr [rdi + 8]
xor rdx, 25711=646F="do" (inverted "od")
or rdx, rcx
je .LBB8_3
movabs rcx, 7308057365947114855=656B6F745F746567="ekot_teg" (inverted "get_toke")
xor rcx, qword ptr [rdi]
movzx edx, word ptr [rdi + 8]
xor rdx, 29550=736E="sn" (inverted "ns")
or rdx, rcx
je .LBB8_5
```
```
.LBB8_3:
xor eax, eax <- returns 0
ret
```
```
.LBB8_5:
mov eax, 1 <- returns 1
ret
```
This is comparable to what `clang` is doing:
https://github.com/rust-lang/rust/issues/61961
## Code and Bytecode
This PR also implements code printing when printing bytecode. For now
this is only enable for tests. It gnerates something like:
```
match param {
"get_a" => { 1u64 },
"get_a_b" => { 2u64 },
"get_b" => { 3u64 },
_ => { 1000u64 },
} @ /home/xunilrj/github/sway/test/src/e2e_vm_tests/test_programs/should_pass/language/match_expressions_all/src/main.sw:23:5
0x00000194 ADDI R17 R59 0x80 ;;
0x00000198 MOVI R18 0x10 ;;
0x0000019c MCP R17 $writable R18 ;;
0x000001a0 MOVI R17 0x7 ;; 0x7 = "get_a_b".len()
@ <autogenerated>:1:1
0x000001a4 LW $writable R59 0x11 ;; R59 + 0x11 = a.len()
0x000001a8 EQ $writable $writable R17 ;; a.len() == 0x7
```
As we can see, not great, but helpful nonetheless. We can (should?)
improve this by better "carrying" spans in all transformations and
lowerings.
## Checklist
- [x] I have linked to any relevant issues.
- [x] I have commented my code, particularly in hard-to-understand
areas.
- [ ] I have updated the documentation where relevant (API docs, the
reference, and the Sway book).
- [ ] If my change requires substantial documentation changes, I have
[requested support from the DevRel
team](https://github.com/FuelLabs/devrel-requests/issues/new/choose)
- [ ] I have added tests that prove my fix is effective or that my
feature works.
- [ ] I have added (or requested a maintainer to add) the necessary
`Breaking*` or `New Feature` labels where relevant.
- [ ] I have done my best to ensure that my PR adheres to [the Fuel Labs
Code Review
Standards](https://github.com/FuelLabs/rfcs/blob/master/text/code-standards/external-contributors.md).
- [ ] I have requested a review from the relevant team or maintainers.
---------
Co-authored-by: Joshua Batty <joshpbatty@gmail.com>
Co-authored-by: IGI-111 <igi-111@protonmail.com>
## Description
Includes critical fix https://github.com/FuelLabs/sway/pull/6212
## Checklist
- [ ] I have linked to any relevant issues.
- [ ] I have commented my code, particularly in hard-to-understand
areas.
- [ ] I have updated the documentation where relevant (API docs, the
reference, and the Sway book).
- [ ] If my change requires substantial documentation changes, I have
[requested support from the DevRel
team](https://github.com/FuelLabs/devrel-requests/issues/new/choose)
- [ ] I have added tests that prove my fix is effective or that my
feature works.
- [ ] I have added (or requested a maintainer to add) the necessary
`Breaking*` or `New Feature` labels where relevant.
- [ ] I have done my best to ensure that my PR adheres to [the Fuel Labs
Code Review
Standards](https://github.com/FuelLabs/rfcs/blob/master/text/code-standards/external-contributors.md).
- [ ] I have requested a review from the relevant team or maintainers.
## Description
Makes the indendation and formatting consistent for forc's action
messages.
### forc build
before

after

### forc test
before

after

## Checklist
- [ ] I have linked to any relevant issues.
- [ ] I have commented my code, particularly in hard-to-understand
areas.
- [ ] I have updated the documentation where relevant (API docs, the
reference, and the Sway book).
- [ ] If my change requires substantial documentation changes, I have
[requested support from the DevRel
team](https://github.com/FuelLabs/devrel-requests/issues/new/choose)
- [ ] I have added tests that prove my fix is effective or that my
feature works.
- [ ] I have added (or requested a maintainer to add) the necessary
`Breaking*` or `New Feature` labels where relevant.
- [ ] I have done my best to ensure that my PR adheres to [the Fuel Labs
Code Review
Standards](https://github.com/FuelLabs/rfcs/blob/master/text/code-standards/external-contributors.md).
- [ ] I have requested a review from the relevant team or maintainers.
## Description
Fixes Clippy warnings after updating to the latest stable Rust toolchain
(1.79).
## Checklist
- [ ] I have linked to any relevant issues.
- [ ] I have commented my code, particularly in hard-to-understand
areas.
- [ ] I have updated the documentation where relevant (API docs, the
reference, and the Sway book).
- [ ] If my change requires substantial documentation changes, I have
[requested support from the DevRel
team](https://github.com/FuelLabs/devrel-requests/issues/new/choose)
- [ ] I have added tests that prove my fix is effective or that my
feature works.
- [ ] I have added (or requested a maintainer to add) the necessary
`Breaking*` or `New Feature` labels where relevant.
- [x] I have done my best to ensure that my PR adheres to [the Fuel Labs
Code Review
Standards](https://github.com/FuelLabs/rfcs/blob/master/text/code-standards/external-contributors.md).
- [x] I have requested a review from the relevant team or maintainers.