-
-
Notifications
You must be signed in to change notification settings - Fork 810
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
feat: immutable variables #2466
Conversation
In general, love this idea. Would you say this is a solution for #1164 though? I think it is (not just "related") |
Codecov Report
@@ Coverage Diff @@
## master #2466 +/- ##
==========================================
+ Coverage 85.61% 85.65% +0.04%
==========================================
Files 90 90
Lines 8946 9023 +77
Branches 2050 2069 +19
==========================================
+ Hits 7659 7729 +70
- Misses 809 815 +6
- Partials 478 479 +1
Continue to review full report at Codecov.
|
003e0cf
to
73b4da3
Compare
Yeah definitely agree, I should've marked it as such in the beginning.
TODO:
|
This pull request introduces 2 alerts when merging 73b4da3 into 030bde6 - view on LGTM.com new alerts:
|
73b4da3
to
dc6a50c
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.
@charles-cooper to comment on the approach and where it fits in with the 0.3.x refactor
621269b
to
a1f33b7
Compare
|
@skellet0r there are a bunch of formatting related changes in here. Could you change your formatter/linter so that the PR is cleaner? |
I'll turn off pre-commit 😢, it's using the defaults in |
Can we do this fixup as a separate PR? Seems like things are out of sync |
@fubuloubu yeh, a PITA, but definitely doable, would just require redoing the PR with pre-commit turned off. |
71b18a5
to
861ac3e
Compare
i'm such a dummy, was going to manually go through this PRs history and pick apart the formatting changes .... |
42861f5
to
1c5d062
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.
Generally looking good!
I left some comments in the code. I think the biggest change to the approach overall is (ab)using the asm symbol resolver to statically get the locations of the immutables in the data section at compile time.
) | ||
offset = self.expr._metadata["type"].position.offset | ||
return LLLnode.from_list( | ||
["sub", "codesize", immutable_section_size - 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.
This is interesting. I wonder if we can get the location of the data section into the runtime code during deploy time.
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.
(Thinking through the approach, it may not be worth it, but if you have some clever ideas here I am all ears.)
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.
Here's an idea: our assembly-to-evm compilation phase has a step which resolves symbols to locations. Since the locations of immutables are statically known (no matter what value they are set to), we can insert symbols into the LLL which directly precede blank space. Basically, _sym_foo doesn't actually take any space in the code. So the runtime data section itself would have something like
_sym_datasection_start
BLANK
_sym_immutable_uint256
JUMPDEST... <32 JUMPDESTs>
_sym_immutable_bytes6
JUMPDEST... <32+6 jumpdests>
Then your code for copying items to LLL would stay the same (it would just overwrite all the jumpdests), but we would know the locations statically.
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.
OK let's add a TODO here for now: TODO: resolve code offsets for immutables at compile time
8cf26db
to
b7e353e
Compare
Changed across codebase to prevent future naming confusion when the `immutable` keyword is added.
Co-authored-by: El De-dog-lo <3859395+fubuloubu@users.noreply.github.com>
Instead when parsing the immutable modify the variable record in the global ctx
b7e353e
to
99217d9
Compare
rebased + fixed mypy error Next steps: should we implement data section in this PR (and importantly how ... ) or implement data section in separate PR (which may for review and testing) |
) | ||
offset = self.expr._metadata["type"].position.offset | ||
return LLLnode.from_list( | ||
["sub", "codesize", immutable_section_size - 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.
OK let's add a TODO here for now: TODO: resolve code offsets for immutables at compile time
Co-authored-by: Charles Cooper <cooper.charles.m@gmail.com>
Co-authored-by: Charles Cooper <cooper.charles.m@gmail.com>
417e6aa
to
713a7bd
Compare
If it is easy to separate out these two changes, I would. they both seem like major changes |
Just want to point out here that this PR does technically introduce a data section - just the structure is mostly implicit. A goal of a future PR would be to refactor the API for accessing and using it. |
What I did
Attempt to add a new keyword immutable to vyper, which enables immutable variables.
Immutable variables act like constants, except they are set at runtime instead of compile-time. At construction, the value of the immutable is copied to the end of the runtime code returned. Runtime code later accesses the immutable value via
codecopy
, and any attempts to modify the variable outside of the constructor raises an error at compile time.Fixes: #1164
Immutables can be any base type + user defined structs + lists
How I did it
Basically, a majority of the edits involved adding the keyword
is_immutable
to a bunch of the primitives and definition classes. Just going through the class inheritence until stuff compiled.The more important changes I think are in the
expr.py
,parser.py
, andmodule.py
files.module.py
Here I modified the
visit_AnnAssign
function to allow theimmutable
keyword, simply adding an additional branch, and doing other validation.Here is also where I went through the class inheritance of certain types to allow for values to be defined as immutable.
expr.py
Here I modified the
parse_Name
function. Essentially there are two cases to look out for when it comes to immutables.In the constructor, immutables are ... well very mutable, so they're simply regular variables, and as such we allocate memory for them and return a pointer to where they are in memory (not an internal variable as those get deallocated).
Outside of the constructor however, we return the pointer to where the immutable is stored in the runtime code. Each immutable is appended to the runtime code, and their offset can be determined by taking the sum of all immutables allocated space, subtracting the offset from the runtime code, and then subtracting that from the actual runtime code size.
codesize - immutable_space + offset
This part actually takes advantage of the new code location introduced in ccb167d.
parser.py
Here I modify the constructor code, After generating the runtime LLL, we create the constructor, which is a simple
[return, 0, ['lll', runtime_code, 0]
LLLnode. I modified this, so that if any immutables are defined we instead copy the runtime code to a spot in front of the last immutable defined (this is to prevent mangling of the immutables in memory), and then append the immutables to the runtime code at their appropriate offsets, and then return the runtime code + the appended immutables.How to verify it
Eventually the following should be able to compile and function correctly: ✔️
Tests include:
Description for the changelog
Enable the definition of
immutable
state variables which must be set within the constructorCute Animal Picture