-
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
IR changes for storage accesses #943
Conversation
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.
Looks great. 🙂
match (self.ptr_map.get(&load_val_ptr), self.ptr_map.get(&key_ptr)) { | ||
(Some(load_val_storage), Some(key_storage)) => { | ||
match (load_val_storage.clone(), key_storage.clone()) { | ||
(Storage::Stack(load_val_offset), Storage::Stack(key_offset)) => { |
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.
Are you able to merge these match statements? Like
(Some(Storage::Stack(load_val_offset)), Some(Storage::Stack(key_offset)))
The load_val_storage
and key_storage
values don't seem to be used again... I'm surprised Clippy isn't suggesting this, unless I'm missing something.
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.
Done for all functions.
comment: "quad state store value".into(), | ||
owning_span: instr_val.get_span(self.context), | ||
}); | ||
} |
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.
Hrmm, is all of this duplicated from the load value? Is it worth it to have a common method to gather up the pointers and offset and then specialise to SRWQ
and SWWQ
?
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.
Done. I wanted to merge the other two functions as well but they're different enough that merging may cause confusion, so I didn't.
} | ||
} | ||
bytes | ||
} |
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 was looking at this thinking it could be done as a one liner, but the best I could come up with is:
let cnv = |c: char| c.to_digit(16).unwrap() as u8;
s.chunks(2).map(|ch| (cnv(ch[0]) << 4) | cnv(ch[1])).collect::<Vec<_>>().try_into().unwrap()
...which I'm not convinced is better. 🙂
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.
This code is mostly a duplicate of another that you wrote to parser b256
values. I ended up merging the two in one helper function.
Instruction::StateLoad { load_val, key } => Doc::text_line(format!( | ||
"state_load ptr {}, key {}{}", | ||
Instruction::StateLoadQuadWord { load_val, key } => Doc::text_line(format!( | ||
"state_load_quad_word ptr {}, ptr {}{}", | ||
namer.name(context, load_val), |
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.
You've switched the key
keyword to be another ptr
, which I think might be confusing. When reading the IR it isn't going to be obvious which argument is which. Maybe state_load_quad_word ptr {}, key ptr {}{}
is a compromise?
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 like having ptr
there to indicate that this is indeed a pointer to a b256, so I now have key ptr {}
as per your recommendation.
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.
Cool.
I've decided to split the storage access work in multiple PRs.
I do have most of the work done for the full flow, but the change is too big to review effectively. This first PR handles IR and IR -> ASM.
Changes in the IR
get_ptr
instruction to also take a pointer type and an offset:get_ptr <base_ptr>, <ptr_ty>, <offset>
. The instruction now convertsbase_ptr
toptr_ty
and then offsets the result byoffset
. The unit ofoffset
here is basically the size ofptr_ty
. So, ifptr_ty
isptr u64
andoffset
is5
, then we basically have to add5*sizeof(ptr_ty)
tobase_ptr
.ptr_cast
for now as its functionality can now be accomplished usingget_ptr
.state_load
andstate_store
with 4 instructions:state_load_word <key>
: returns a word (u64
) from the storage locationkey
.key
has to be ab256
.state_load_quad_word <val>, <key>
: reads 4 words (b256
) from storage locationkey
intoval
whereval
is a pointer to ab256
.state_store_word <val>, <key>
: storesval
to storage locationkey
.val
has to be au64
.state_store_quad_word <val>, <key>
: stores 4 words pointed to byval
to storage locationkey
.Changes in IR -> ASM
get_ptr
.Notes
state_load_*
/state_store_*
.get_ptr
arguments, especiallyload
andstore
, but for now, the new arguments are only exercised forstate_load_*
andstate_store_*
.