-
Notifications
You must be signed in to change notification settings - Fork 5.8k
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
Treat builtins separately in Yul AST #15347
base: develop
Are you sure you want to change the base?
Conversation
d93fc88
to
5f7b564
Compare
340ffbc
to
b69030d
Compare
a5e3f71
to
52e9e4b
Compare
39fdd32
to
dec3a9d
Compare
dec3a9d
to
7370d5a
Compare
d73a5bf
to
ec2536e
Compare
01fe1a4
to
108cf86
Compare
03b01c1
to
4938075
Compare
a78635f
to
48de861
Compare
75ef5e6
to
4db506f
Compare
3b9c384
to
c05a6b2
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.
Here's some initial feedback. Not a full review yet.
599255e
to
f0e9f4d
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.
I haven't managed go get through it all yet, but here's some feedback so far.
I think we may still need some adjustments in EVMDialect
implementation. Also, I think that Dialect
should be stored in Object
, though that could be done in a separate PR to avoid making this one even larger.
libyul/AST.h
Outdated
/// Builtin function | ||
struct BuiltinName { langutil::DebugData::ConstPtr debugData; BuiltinHandle handle; }; | ||
/// Identifier for function names | ||
using FunctionHandle = std::variant<YulName, BuiltinHandle>; |
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.
We could add a bit more detail here:
/// Builtin function | |
struct BuiltinName { langutil::DebugData::ConstPtr debugData; BuiltinHandle handle; }; | |
/// Identifier for function names | |
using FunctionHandle = std::variant<YulName, BuiltinHandle>; | |
/// AST Node representing a reference to one of the built-in functions (as defined by the dialect). | |
/// In the source it's an actual name, while in the AST we only store a handle that can be used to find the the function in the Dialect. | |
struct BuiltinName { langutil::DebugData::ConstPtr debugData; BuiltinHandle handle; }; | |
/// Type that can refer to both user-defined functions and built-ins. | |
/// Technically the AST allows these names to overlap, but this is not possible to represent in the source. | |
using FunctionHandle = std::variant<YulName, BuiltinHandle>; |
libyul/YulName.h
Outdated
#include <libyul/YulString.h> | ||
|
||
namespace solidity::yul | ||
{ | ||
class YulString; |
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.
Any advantage to doing this? It seems that you'd want to include YulString.h
whenever you use YulName
anyway. And we'll unify them eventually.
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.
The advantage is that I am now including YulName.h
in ASTForward.h
. This is required if I want to define FunctionName
in there, as the identifier for a user defined function is a YulName
(or currently: YulString
). So by making YulName.h
forwarding, I don't implicitly include YulString.h
in ASTForward.h
.
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.
Wouldn't it be more typical for just forward-declare YulName
there? Or, I guess, redefine since it's just an alias.
In any case, it's fine, I was just curious why it was done this way.
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.
Right, redefining is an option :)
libyul/Dialect.h
Outdated
/// @returns the builtin function of the given name or a nullptr if it is not a builtin function. | ||
virtual BuiltinFunction const* builtin(YulName /*_name*/) const { return nullptr; } | ||
virtual std::optional<BuiltinHandle> builtin(std::string_view /*_name*/) const { return std::nullopt; } | ||
|
||
virtual BuiltinFunction const& builtinFunction(BuiltinHandle const&) const; |
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.
These names are a bit inconsistent given that, below, the ones ending in Function
return a handle, while here it's the opposite. And builtin()
and builtinFunction()
sound too much like the same thing.
A better convention might be to keep builtin()
as the one returning BuiltinFunction
, and rename the other one to findBuiltin()
. This better reflects which one is doing more work.
Then the ones ending with Function
could be renamed to end with Handle
or FunctionHandle
. Or maybe left as is - no longer having builtinFunction()
that resembles them already makes it less confusing.
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.
Also, docstring needs updating. Now it's nullopt
, not nullptr
. You could informally say just "null".
libyul/Dialect.h
Outdated
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 like Dialect::fixedFunctionNames()
isn't implemented by any dialect. Back when we had the Ewasm dialect, it contained one name there: "main"
. I think we can remove it as an Ewasm left-over.
If you do want to keep it, then I guess it should be using returning either BuiltinHandle
s or string
s.
libyul/Object.h
Outdated
@@ -93,11 +95,12 @@ struct Object: public ObjectNode | |||
public: | |||
/// @returns a (parseable) string representation. | |||
std::string toString( | |||
Dialect const& _dialect, |
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 think we should store the Dialect
in the Object
(or AST
). After this PR the Object
on its own is no longer enough to interpret the AST, even in non-source form. And also it's not like we can print it in arbitrary dialect and still get something that makes sense.
But that's probably better done as a separate refactor on top of it. The PR is already quite large and it would be harder to review these things together.
libyul/AsmParser.cpp
Outdated
auto const raiseAssignToBuiltinError = [this](std::string const& _name) { | ||
fatalParserError(6272_error, "Cannot assign to builtin function \"" + _name + "\"."); | ||
}; |
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.
If this was pulled out because of verbatim
, now you can put it back. Having it singled out like this is a bit distracting :)
Same with uninvokedBuiltinError()
below. You can also use util::unreachable()
to avoid having to return a dummy value there.
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.
Also, shouldBreak
would be better off called something like foundLastVariable
or foundListEnd
and be the loop condition (it could also be a do
..while
loop).
One more thing. Not sure if it's worth it at this point, since it's extra effort for you, but after going through most of the PR it seems to me that there is a way to split it into two smaller parts quite cleanly, and smaller PRs would get through review faster. I think that the introduction of |
I'll do as you suggested and split the PR into two. It is more work for me but probably downstream more efficient, all things considered. |
f0e9f4d
to
ea36743
Compare
Comparing against current develop (including
|
a59ec52
to
371647c
Compare
ea36743
to
a3ef44a
Compare
This pull request is stale because it has been open for 14 days with no activity. |
Depends on