Skip to content
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

Merged
merged 3 commits into from
Mar 16, 2022

Conversation

mohammadfawaz
Copy link
Contributor

@mohammadfawaz mohammadfawaz commented Mar 14, 2022

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

  • Modified the get_ptr instruction to also take a pointer type and an offset: get_ptr <base_ptr>, <ptr_ty>, <offset>. The instruction now convertsbase_ptr to ptr_ty and then offsets the result by offset. The unit of offset here is basically the size of ptr_ty. So, if ptr_ty is ptr u64 and offset is 5, then we basically have to add 5*sizeof(ptr_ty) to base_ptr.
  • Removed ptr_cast for now as its functionality can now be accomplished using get_ptr.
  • Replaced state_load and state_store with 4 instructions:
    • state_load_word <key>: returns a word (u64) from the storage location key. key has to be a b256.
    • state_load_quad_word <val>, <key>: reads 4 words (b256) from storage location key into val where val is a pointer to a b256.
    • state_store_word <val>, <key>: stores val to storage location key. val has to be a u64.
    • state_store_quad_word <val>, <key>: stores 4 words pointed to by val to storage location key.
  • Modified the parser to handle contracts and function selectors

Changes in IR -> ASM

  • Basically supporting the 4 new IR instructions above and the new syntax for get_ptr.

Notes

  • The IR generator is expected to break each storage access into a list of state_load_*/state_store_*.
  • The ASM generator will need some additional updates to support the new get_ptr arguments, especially load and store, but for now, the new arguments are only exercised for state_load_* and state_store_*.

@mohammadfawaz mohammadfawaz added compiler General compiler. Should eventually become more specific as the issue is triaged enhancement New feature or request labels Mar 14, 2022
@mohammadfawaz mohammadfawaz self-assigned this Mar 14, 2022
Copy link
Contributor

@otrho otrho left a 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)) => {
Copy link
Contributor

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.

Copy link
Contributor Author

@mohammadfawaz mohammadfawaz Mar 15, 2022

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),
});
}
Copy link
Contributor

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?

Copy link
Contributor Author

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
}
Copy link
Contributor

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. 🙂

Copy link
Contributor Author

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),
Copy link
Contributor

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?

Copy link
Contributor Author

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.

Copy link
Contributor

@otrho otrho left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cool.

@mohammadfawaz mohammadfawaz merged commit 72508e3 into master Mar 16, 2022
@mohammadfawaz mohammadfawaz deleted the mohammadfawaz/storage_ir_and_get_ptr branch March 16, 2022 01:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
compiler General compiler. Should eventually become more specific as the issue is triaged enhancement New feature or request
Projects
Archived in project
Development

Successfully merging this pull request may close these issues.

2 participants