-
Notifications
You must be signed in to change notification settings - Fork 11.3k
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
[move] Fixed locals disassembly #20747
Conversation
The latest updates on your projects. Learn more about Vercel for Git ↗︎
3 Skipped Deployments
|
parameter_len + local_idx, | ||
signature, | ||
)?; | ||
self.disassemble_type_for_local(buffer, function_source_map, local_idx, signature)?; |
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.
I don't think this is quite right. There's a slight mismatch here due to an underlying problem/mismatch between source maps and compiled modules:
- In the bytecode all parameters are laid out in locals (so the first
parameter_len
local indices in the bytecode are the parameters). - In the function source map, we add parameters in to the
parameters
field, but not the locals.
I see two possibilities here:
- Pass
local_idx + parameter_len
here (since this is the index into the bytecode, so we want to skip the parameters here). - Update the source map generation to also add the parameters to the
locals
(and in this case theparameters
field in the function source map should be removed).
I prefer option (2) but that's a lot more work than just updating the index here, so if you need this to unblock you updating the index just here is probably fine.
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.
I don't think this is going to work as in disassemble_locals
we actually iterate over locals indexes from the source map:
for (local_idx, (name, _)) in function_source_map.locals.iter().enumerate() {
...
}
If we use local_idx +parameter_len
to get the type, we will miss some of them as locals signature only contains locals types:
L0: %#7: SomeEnum
L1: %#8: u64
L2: __match_tmp%#match_subject#2#2#0: u64
L3: __match_tmp%#unpack_subject#1#1#0: ERROR[Unable to get type for local at index 6]
L4: field#3#0: ERROR[Unable to get type for local at index 7]
L5: res#1#0: ERROR[Unable to get type for local at index 8]
That being said, with the current solution locals indexes displayed with locals disassembly do not match what's in the disassembled bytecode due to what you observed ("in the bytecode all parameters are laid out in locals") and we need to bump them up using parameter_len
(note that now MoveLoc
and StLoc
disassembly's indexes much parameter and local indexes):
public foo(e#0#0: SomeEnum, p1#0#0: u64, p2#0#0: u64): u64 * u64 {
L3: %#7: u64
L4: %#8: u64
L5: __match_tmp%#match_subject#2#2#0: &SomeEnum
L6: __match_tmp%#unpack_subject#1#1#0: SomeEnum
L7: field#3#0: u64
L8: res#1#0: u64
B0:
0: MoveLoc[0](e#0#0: SomeEnum)
1: StLoc[6](__match_tmp%#unpack_subject#1#1#0: SomeEnum)
...
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.
Changes look good to me!
Description
It looks like locals are currently not disassembled correctly when running Move disassembler and this PR contains a fix. In particular, consider the following Move code:
When running disassembler on the
M1
module, the following 3 locals are reported in the disassembly:However, 6 locals are reported in the source map:
The same number of locals is also reported in the trace generated out of the test function in
M1
.It looks like the disassembler incorrectly assumes that function parameters are included in the locals and only locals beyond the (optional) initial number of parameters should be counted. After making the adjustment to ignore the parameters when disassembling locals, the following is reported in the disassembly which is consistent with the number (and names) of the locals in the source map and with the types of the locals in the trace:
Test plan
All tests should pass