-
Notifications
You must be signed in to change notification settings - Fork 6.1k
Support ethdebug source locations under EOF #15994
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
base: develop
Are you sure you want to change the base?
Conversation
20d6a64
to
fb559fb
Compare
e6a1055
to
2a91773
Compare
d82b70c
to
0fd1232
Compare
0fd1232
to
cf6aa71
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.
lgtm
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 want to take a closer look at this, especially the Assembly.cpp
part, but for now just a few small annoyances I found while doing a quick initial pass.
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 output here is quite long and seems to have little to do with ethdebug itself (the ethdebug JSON gets stripped). Do we need it all? What's the point?
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 I just added it because there is the same test for non-eof. And looking at it now, I agree. There doesn't seem to be much value to keep it (or: them) around, especially with #16009 around the corner. I have removed this one.
test/cmdlineTests/standard_output_debuginfo_ethdebug_compatible_eof/input.json
Outdated
Show resolved
Hide resolved
3c02df0
to
f9a0985
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.
LGTM!
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.. at least on the cli I just saw that ethdebug returns null
for the interface (e.g. using test/libsolidity/semanticTests/interfaceID/homer.sol
) - I guess we want an empty json object there. I think it would be nice to add a small test for that simple interface case.
42d5d8f
to
7eecf23
Compare
"C": { | ||
"evm": { | ||
"bytecode": { | ||
"ethdebug": null |
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, I thought those would get automatically removed.
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.
it's even better if they don't. if you request ethdebug output there should be an ethdebug output artifact there that indicates that there is no ethdebug output :)
regarding the |
7eecf23
to
e696889
Compare
e696889
to
667d2e3
Compare
libevmasm/Assembly.cpp
Outdated
m_instructionLocations.emplace_back(LinkerObject::InstructionLocation{ | ||
.start = m_instructionLocationStart, | ||
.end = end, | ||
.assemblyItemIndex = m_assemblyItemIndex | ||
}); |
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.
Shouldn't this be as follows:
m_instructionLocations.emplace_back(LinkerObject::InstructionLocation{ | |
.start = m_instructionLocationStart, | |
.end = end, | |
.assemblyItemIndex = m_assemblyItemIndex | |
}); | |
m_instructionLocations.emplace_back( | |
m_instructionLocationStart, | |
end, | |
m_assemblyItemIndex | |
); |
Otherwise it's equivalent to a push_back
, i.e. copied instead of constructed in place.
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.
yup but clang (in the version we use it at least) doesn't like that :( in the end it's POD though so the effect should be marginal at best
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'd suggest using push_back()
in that situation though. The whole shtick of emplace_back()
is that it will perform an implicit conversion. When you know the exact type, you don't really want that.
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 I'd rather say the whole shtick is that stuff is created in-place (if possible) and we avoid an additional move. This is still the case if I know the precise type.
In our specific case there is exactly zero performance (or copy/move semantic) difference between push_back
and emplace_back
- both perform a move into an allocated memory region and that is it. For the sake of clarity I have changed it to push_back
, though.
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.
But the creation in place happens via an implicit conversion (basically, though choosing a constructor, though it could be one with multiple args; which is why sometimes use explicit
to prevent such conversions).
I'm just pointing this out because for some time I've seen a push to use the emplace
-style methods everywhere and wanted to push back against it a little :P. push_back()
actually seems to me like a better default, because it's stricter about what it accepts. I'd only use emplace_back()
when I know I want such a conversion or construction in-place.
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 don't want to derail this PR and I think the push-back is great! Although I do have to push back a bit on the push-back. You absolutely can have an explicit constructor and still use emplace_back
by virtue of its args. It is simply forwarded into std::construct_at
/ placement new. So this can perform implicit conversion but doesn't have to :)
For me personally it's more of a performance thing. For small objects in a tight loop or objects that are expensive to move it can make quite a bit of difference. Implicit conversions are (sometimes) mean.
libevmasm/Assembly.cpp
Outdated
/// instruction locations vector. | ||
/// If the instruction decomposes into multiple individual evm instructions, `emit` can be | ||
/// called for all but the last one (which will be emitted by the destructor). | ||
class InstructionLocationEmitter |
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.
Was this refactor strictly necessary in this PR?
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.
no. it does however disentangle the ethdebug metadata stuff a bit from the assembly items themselves and unifies the style.
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.
Well, it would have been better off as a separate PR. Actually wanted to suggest that at some point.
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.
Doesn't feel like it is necessary in this case. It is a cosmetic change and not a ton of lines of change either. Not that it matters now.
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.
Well, the main reason is that it touches a critical part of the compiler and is completely independent of the rest of the PR. I was only really interested in this part, and it looks fine so would be best if we could merge it right away (not sure what the state of the rest is, but no reason for it to hold it back).
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.
That makes sense. I'll extract it!
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.
-> #16052
schema::program::Instruction::Operation operation; | ||
operation.mnemonic = instructionInfo(static_cast<Instruction>(_linkerObject.bytecode[_start]), _assembly.evmVersion()).name; | ||
static size_t constexpr instructionSize = 1; | ||
if (_start + instructionSize < _end) |
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.
Might even make sense to replace this with an assert as this could end up with an empty operation, which is not desired?
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.
there is an assert that start < end
. which leaves start + 1== end
as possibility, ie, an op with no argument data - which is desired and possible I'd think
schema::materials::SourceRange::Range locationRange(langutil::SourceLocation const& _location) | ||
{ | ||
return { | ||
.length = schema::data::Unsigned{_location.end - _location.start}, |
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.
Assert
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 assert already is in Unsigned
.
667d2e3
to
bcf1c34
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 only looked at the Assembly
changes so far, but they look good. We could merge that if you extract it into a separate PR.
@@ -4,7 +4,7 @@ Language Features: | |||
|
|||
|
|||
Compiler Features: | |||
|
|||
* ethdebug: Experimental support for instructions and source locations under EOF. |
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.
* ethdebug: Experimental support for instructions and source locations under EOF. | |
* ethdebug: Experimental support for instructions and source locations under EOF. |
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.
Uhh. Happy to fix this - but why? It's not like there's a blank line between bullet point list and headline anywhere else.
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.
Ah, my bad, should have been the other way around - an extra empty line below :)
but why?
Two empty lines between sections.
Maybe we should just change the convention to a single line? No one seems to be able to keep it straight or see it in the diff and it gets changed by PRs back and forth. I usually ignore it but I got annoyed enough seeing it again to suggest a correction :)
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.
Haha yeah, that explains it. Might've also been my pre-coffee confusion that I didn't realize you meant the blank line below. I am absolutely fine with changing it to one line in any case! :)
af84571
to
aad6fca
Compare
aad6fca
to
739761a
Compare
EthdebugSchema
header with the relevant part of the schema mapped to structs with correspondingto_json
methods and validations(-1, -1)
)assembleEOF
Fixes the unoptimized part of #15978.
Fixes #15998.