Open fubuloubu opened 4 years ago
Vyper is easy enough to obtain this info for from the source map (see: https://github.com/vyperlang/vyper-debug), but having this in place ensures we have support for this when more advanced optimizations of storage slots and/or memory (or using the stack) are in play.
Meeting notes: @fubuloubu to define format
We're going to need something a little more advanced than this if/when we implement tight packing of variables in storage, but this is a provisional format:
bar: uint256
@external
@nonreentrant("lock")
def foo():
foo: uint256 = 0
{
"foo.lock": {
"type": "uint256",
"location": "storage",
"slot": 0
},
"bar": {
"type": "uint256",
"location": "storage",
"slot": 1
}
}
Thinking through this a bit more, the format for nonreentrant keys should not reference the function name because the same nonreentrant lock can be used on multiple functions. Instead, to make sure it is disambiguated from variables with the same name (in the below case, a variable like baz: uint256
), in the exported layout the key would be "nonreentrant.<lock name>"
.
bar: uint256
@external
@nonreentrant("baz")
def foo():
foo: uint256 = 0
{
"nonreentrant.baz": {
"type": "nonreentrant lock",
"location": "storage",
"slot": 0
},
"bar": {
"type": "uint256",
"location": "storage",
"slot": 1
}
}
should the type be an actual abi type, and then add a description field or something that let's us specify internal vs. user-defined storage?
should the type be an actual abi type, and then add a description field or something that let's us specify internal vs. user-defined storage?
You mean the type of the lock?
I thought about this but I'm not sure how I feel about advertising it's some specific type as it's not like something you would ever .. ABI encode or pass to a function or do anything you would with a normal ABI type. As far as the user is concerned it's magic, and internally it can be a bool or a bit or a bytes32 or what have you, especially if we decide to change the packing.
should the type be an actual abi type, and then add a description field or something that let's us specify internal vs. user-defined storage?
You mean the type of the lock?
I thought about this but I'm not sure how I feel about advertising it's some specific type as it's not like something you would ever .. ABI encode or pass to a function or do anything you would with a normal ABI type. As far as the user is concerned it's magic, and internally it can be a bool or a bit or a bytes32 or what have you, especially if we decide to change the packing.
so that type is the "internal type" then?
Simple Summary
Output the storage slot and memory index mapping for Vyper variables
Motivation
A Symbol Table is a mapping between variables and their corresponding register locations. It is helpful to tools like debuggers to have this information so that it can use human-readable names (from the source code) when querying data from dynamic execution. For Vyper, because the EVM has several different memory spaces (storage slots, program memory, and the stack) it would be helpful to provide all of these in a table when compiling a program. Tools like https://tenderly.dev/ use this for advanced debugging.
Specification
TBD what format this would take, and the external API to access it.
Backwards Compatibility
No backwards compatibility issues.
Dependencies
No dependencies.
Copyright
Copyright and related rights waived via CC0