-
Notifications
You must be signed in to change notification settings - Fork 5.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Represent small values as single bytes #4929
Conversation
fddc699
to
0bdf48e
Compare
65d5718
to
9dca3bd
Compare
f923ebf
to
3c12320
Compare
The most important changes made by this PR: 1 - u8, bool and unit are 1 byte now; That means that [u8;3], for example, is 3 bytes. struct A { a: u8, b: u64 }
let a = A { a: 1, b: 2 } // memory: 10000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000010 4 - Type checking/inference on arrays changed a little bit. Now the first item of the array does not necessarily start as 5 - All the |
636eaa5
to
d56632a
Compare
c37e200
to
4bbf431
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good job! I have a feeling finding all the places in code that need to be touched by this change wasn't trivial at all.
Speaking of which, my wish is to see #5227 implemented soon 😉
And afterwards same support for u16
and u32
😄
(And afterwards shuffling struct types to get optimized data layout 😄)
bd6e3a4
to
a806f58
Compare
One question. In the sway-core/src/asm_generation/fuel/functions.rs line 799 this is the way how the
Is this the right formula for getting |
That is a nice question. I think this is wrong. But we have older tests expecting string arrays to be padded. My idea was to fix this when doing the layout issue you are working at the moment. |
Ok I'll then take a closer look at the padding logic for string arrays and see if something needs to be changed. |
Storage definitely makes heavy assumptions on memory layout.
This code has assumed that the raw type sizes are word aligned. Our new
for variant A, the I am fixing this on the go and extending test while refactoring access to memory layout information. |
Yes, but I don't remember a place that deals with variant size alone.
|
It looks to me that So I assume that Unfortunately I have issues running locally the tests that require contract deployment so I cannot immediately test the described case locally and on the build machine I got an error indeed with the changed test, but saying that the contract cannot be found?! Will let you know about the test outcome once I manage to run it. |
In the end, there were two issues in serializing constants into storage slots. One was the one explained above. In case of enums with one byte variants mixed with (multi) word variants the one byte variants were not properly padded (there was an additional shift to the right as commented above.)
Interestingly, the existing tests didn't catch the issue, because the storage access test is actually not calling the contract methods, only one, and the basic storage test that is very detailed didn't have constants in the storage statement that would reproduce the issue. Note that the issue is only in initializing the storage via constants. Reading and writing from and into the storage works fine afterwards. That's why the existing tests pass. I've pushed the fix together with the test suit. @xunilrj Can you please triple-check the logic? 😄 Also, the existing storage tests should be extended to check structs, but I've already started doing that in the refactoring of the access to the memory layout information. So I propose to do it there and leave the existing storage tests in this PR as they are. |
As it goes, fixed one bug introduced another 😄 It turned out we do have testing of storage initialization within the SDK tests (which I, shame on me, never run locally so far). These tests also need to be extended to cover one-byte values in enums. Long story short, it looks like we will need a logic here similar to one we have in initializing data section, where the outer context (struct or enum) decides on the padding (left or right) of the single byte values. It has nothing to do with endianess as wrongly pointed above. Let me now triple-check that changed logic on my own before pushing 😄, extend the tests etc. and provide the fix. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Storage initialization still needs to be fixed as pointed in the comment above.
6ecd2d7
to
64945a3
Compare
Description
This change leverages the SB/LB instructions to change the memory representation of all small enough values to make them fit in a single byte instead of a full word.
The type size and passing calculations have been changed to align elements of structs and enums to full words.
Structs and data section entries are filled with right-padding to align their elements to words. Enums are still left-padded. The Data section generation has been refactored to allow for these two padding modes.
Arrays and slices contain no inner padding, byte sequences will now be properly consecutive and packed. Though, as a whole, they may be right padded in certain circumstances to maintain word alignment.
Direct usages of LW/SW have been changed to LB/SB where appropriate.
The LWDataId virtual instruction has been changed to LoadDataId to better represent the fact that it can load both word and byte sized values.
Checklist
Breaking*
orNew Feature
labels where relevant.