-
Notifications
You must be signed in to change notification settings - Fork 6.2k
Add --import-asm-json input mode. #12704
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
Conversation
9bcc135
to
67a69aa
Compare
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
4128beb
to
4b7d64c
Compare
I assume the question above has been resolved, right? |
@@ -451,6 +455,13 @@ void CommandLineParser::parseOutputSelection() | |||
CompilerOutputs::componentName(&CompilerOutputs::ewasm), | |||
CompilerOutputs::componentName(&CompilerOutputs::ewasmIR), | |||
}; | |||
static set<string> const evmAssemblyJsonImportModeOutputs = { |
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 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.
@cameel can you answer this?
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.
Yeah, looks sensible. I think they all should be possible to generate from imported assembly.
My only doubt would be about binaryRuntime
. If it comes from compiling a contract, we do have the construction/runtime code split. Do we always have it with arbitrary assembly 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.
@cameel yeah good point. An initial version of this PR did not support any binaryRuntime
stuff - because I also saw it like you seem to see it. If I recall correctly, @chriseth wanted to have support for binaryRuntime
and also support for the srcmap
& srcmap-runtime
. I understood it like that it would be great to support as many output modes that are usually also working. To achieve this, of course, we need to have some presumption about the imported assembly json. E.g. structure related to creational code vs. runtime code. Right now not every (well-formed & correct) assembly json will lead be create correct output (e.g. missing "runtime section").
@chriseth @ekpyron This question was more about the high-level view on this PR: if someone uses the asm json import, what should be the supported output-modes. Are my current assumptions to limit and/or support specific output-modes correct?
The main use-case for this I understood like this: someone wrote in contract in solidity, this contract gets exported to asm json, the user may do some tweaks & optimisations on the given code, but e.g. there is no need to change the initial structure e.g. creational code
vs runtime code
. Of course the user could add more data sections - but the initial structure should not get modified (creational
vs runtime
). As of now, I also did not really check the behaviour of multiple data sections etc - I guess it should just work, but I'm not entirely sure about this.
The main question is: are my assumptions correct? Do we want to support these output modes for assembly json import? Also for #12704 (comment) - where my assumptions correct to limit and/or support these?
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 for #12704 (comment) - where my assumptions correct to limit and/or support these?
This second check is redundant. It's just the opposite of the supported input modes, isn't it?
@@ -941,9 +959,27 @@ void CommandLineParser::processArgs() | |||
for (auto& option: conflictingWithStopAfter) | |||
checkMutuallyExclusive({g_strStopAfter, option}); | |||
|
|||
array<string, 11> const conflictingWithAsmJsonImport{ |
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 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.
Again @cameel
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.
Not completely sure about storageLayout
. So we lose that info at assembly level?
And --gas
- so the estimator must be working at the Solidity level I assume and not by looking at opcodes?
By the way, putting it here seems redundant to me. You already do this check in parseOutputSelection()
so this will never fail. conflictingWithStopAfter
was here because it's just a regular option, not an input mode. And conflictingWithStopAfter
should eventually be integrated into validOptionInputModeCombinations
above anyway - this was being refactored in #12166 but it's stalled for now.
Regarding the mismatch in the optimised byte-code:
Basically for these compilations the used optimiser(-steps) are different. That's why we see a difference in the byte-code. (A) uses class I think it totally make sense to allow |
string const evmSourceName = m_evmAssemblyJson.begin()->first; | ||
Json::Value const evmJson = m_evmAssemblyJson.begin()->second; | ||
|
||
evmasm::Assembly::OptimiserSettings optimiserSettings; |
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 saw somewhere a optimiser-settings transform function.
m_contracts[evmSourceName].evmAssembly = make_shared<evmasm::Assembly>(true, evmSourceName); | ||
m_contracts[evmSourceName].evmAssembly->loadFromAssemblyJSON(m_evmAssemblyJson[evmSourceName]); | ||
if (m_optimiserSettings.enabled) | ||
m_contracts[evmSourceName].evmAssembly->optimise(optimiserSettings); |
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.
m_contracts[evmSourceName].evmRuntimeAssembly->setSources(m_contracts[evmSourceName].evmAssembly->sources()); | ||
m_contracts[evmSourceName].evmRuntimeAssembly->loadFromAssemblyJSON(m_evmAssemblyJson[evmSourceName][".data"]["0"], false); | ||
if (m_optimiserSettings.enabled) | ||
m_contracts[evmSourceName].evmRuntimeAssembly->optimise(optimiserSettings); |
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.
|
||
m_contracts[evmSourceName].evmRuntimeAssembly = make_shared<evmasm::Assembly>(false, evmSourceName); | ||
m_contracts[evmSourceName].evmRuntimeAssembly->setSources(m_contracts[evmSourceName].evmAssembly->sources()); | ||
m_contracts[evmSourceName].evmRuntimeAssembly->loadFromAssemblyJSON(m_evmAssemblyJson[evmSourceName][".data"]["0"], false); |
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.
@chriseth @ekpyron Does it make sense to load the runtime assembly hardcoded from ".data"[0]
here? Not sure whether we should do this dynamically - e.g. that the correct run time will be taken automatically. I guess for this I would need to analyse the "deploy" code. Not sure whether we really want this. What are your opinions?
item.m_modifierDepth = modifierDepth; | ||
if (!value.empty()) | ||
item.setJumpType(value); | ||
result = item; |
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.
result = item; | |
return item; |
{ | ||
if (!value.empty()) | ||
data = u256(value); | ||
updateUsedTags(data); |
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 better to compute that once at the end from the full list of items?
else if (name == "PUSH [$]") | ||
{ | ||
if (!value.empty()) | ||
data = u256("0x" + value); |
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.
Please check that this works properly when the value starts with a zero (i.e. leading zeros may be removed somewhere in the process).
|
||
vector<Json::Value> Assembly::assemblyItemAsJSON(AssemblyItem const& _item, int _sourceIndex) const | ||
{ | ||
vector<Json::Value> result; |
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 return a single Json::Value?
_item.m_modifierDepth, | ||
_item.location().start, | ||
_item.location().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.
Can this be simplified so that we don't have to pass all three values all the time?
After talking to @chriseth, we decided to split-up this PR. |
Replaces #11807.
Replaced by #12799,#12809 & #12834.