mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Provide runtime object in Yul mode.
This commit is contained in:
parent
142a6b0d4f
commit
f92a4f1965
@ -52,6 +52,7 @@ public:
|
||||
AssemblyItem newSub(AssemblyPointer const& _sub) { m_subs.push_back(_sub); return AssemblyItem(PushSub, m_subs.size() - 1); }
|
||||
Assembly const& sub(size_t _sub) const { return *m_subs.at(_sub); }
|
||||
Assembly& sub(size_t _sub) { return *m_subs.at(_sub); }
|
||||
size_t numSubs() const { return m_subs.size(); }
|
||||
AssemblyItem newPushSubSize(u256 const& _subId) { return AssemblyItem(PushSubSize, _subId); }
|
||||
AssemblyItem newPushLibraryAddress(std::string const& _identifier);
|
||||
AssemblyItem newPushImmutable(std::string const& _identifier);
|
||||
|
@ -30,6 +30,7 @@
|
||||
#include <libevmasm/Instruction.h>
|
||||
#include <libsolutil/JSON.h>
|
||||
#include <libsolutil/Keccak256.h>
|
||||
#include <libsolutil/CommonData.h>
|
||||
|
||||
#include <boost/algorithm/string/predicate.hpp>
|
||||
|
||||
@ -1127,16 +1128,29 @@ Json::Value StandardCompiler::compileYul(InputsAndSettings _inputsAndSettings)
|
||||
|
||||
stack.optimize();
|
||||
|
||||
MachineAssemblyObject object = stack.assemble(AssemblyStack::Machine::EVM);
|
||||
MachineAssemblyObject object;
|
||||
MachineAssemblyObject runtimeObject;
|
||||
tie(object, runtimeObject) = stack.assembleAndGuessRuntime();
|
||||
|
||||
if (isArtifactRequested(
|
||||
_inputsAndSettings.outputSelection,
|
||||
sourceName,
|
||||
contractName,
|
||||
{ "evm.bytecode", "evm.bytecode.object", "evm.bytecode.opcodes", "evm.bytecode.sourceMap", "evm.bytecode.linkReferences" },
|
||||
wildcardMatchesExperimental
|
||||
))
|
||||
output["contracts"][sourceName][contractName]["evm"]["bytecode"] = collectEVMObject(*object.bytecode, object.sourceMappings.get(), false);
|
||||
for (string const& objectKind: vector<string>{"bytecode", "deployedBytecode"})
|
||||
{
|
||||
auto artifacts = util::applyMap(
|
||||
vector<string>{"", ".object", ".opcodes", ".sourceMap", ".linkReferences"},
|
||||
[&](auto const& _s) { return "evm." + objectKind + _s; }
|
||||
);
|
||||
if (isArtifactRequested(
|
||||
_inputsAndSettings.outputSelection,
|
||||
sourceName,
|
||||
contractName,
|
||||
artifacts,
|
||||
wildcardMatchesExperimental
|
||||
))
|
||||
{
|
||||
MachineAssemblyObject const& o = objectKind == "bytecode" ? object : runtimeObject;
|
||||
if (o.bytecode)
|
||||
output["contracts"][sourceName][contractName]["evm"][objectKind] = collectEVMObject(*o.bytecode, o.sourceMappings.get(), false);
|
||||
}
|
||||
}
|
||||
|
||||
if (isArtifactRequested(_inputsAndSettings.outputSelection, sourceName, contractName, "irOptimized", wildcardMatchesExperimental))
|
||||
output["contracts"][sourceName][contractName]["irOptimized"] = stack.print();
|
||||
|
@ -198,22 +198,7 @@ MachineAssemblyObject AssemblyStack::assemble(Machine _machine) const
|
||||
switch (_machine)
|
||||
{
|
||||
case Machine::EVM:
|
||||
{
|
||||
MachineAssemblyObject object;
|
||||
evmasm::Assembly assembly;
|
||||
EthAssemblyAdapter adapter(assembly);
|
||||
compileEVM(adapter, false, m_optimiserSettings.optimizeStackAllocation);
|
||||
object.bytecode = make_shared<evmasm::LinkerObject>(assembly.assemble());
|
||||
yulAssert(object.bytecode->immutableReferences.empty(), "Leftover immutables.");
|
||||
object.assembly = assembly.assemblyString();
|
||||
object.sourceMappings = make_unique<string>(
|
||||
evmasm::AssemblyItem::computeSourceMapping(
|
||||
assembly.items(),
|
||||
{{scanner().charStream() ? scanner().charStream()->name() : "", 0}}
|
||||
)
|
||||
);
|
||||
return object;
|
||||
}
|
||||
return assembleAndGuessRuntime().first;
|
||||
case Machine::EVM15:
|
||||
{
|
||||
MachineAssemblyObject object;
|
||||
@ -240,6 +225,46 @@ MachineAssemblyObject AssemblyStack::assemble(Machine _machine) const
|
||||
return MachineAssemblyObject();
|
||||
}
|
||||
|
||||
pair<MachineAssemblyObject, MachineAssemblyObject> AssemblyStack::assembleAndGuessRuntime() const
|
||||
{
|
||||
yulAssert(m_analysisSuccessful, "");
|
||||
yulAssert(m_parserResult, "");
|
||||
yulAssert(m_parserResult->code, "");
|
||||
yulAssert(m_parserResult->analysisInfo, "");
|
||||
|
||||
evmasm::Assembly assembly;
|
||||
EthAssemblyAdapter adapter(assembly);
|
||||
compileEVM(adapter, false, m_optimiserSettings.optimizeStackAllocation);
|
||||
|
||||
MachineAssemblyObject creationObject;
|
||||
creationObject.bytecode = make_shared<evmasm::LinkerObject>(assembly.assemble());
|
||||
yulAssert(creationObject.bytecode->immutableReferences.empty(), "Leftover immutables.");
|
||||
creationObject.assembly = assembly.assemblyString();
|
||||
creationObject.sourceMappings = make_unique<string>(
|
||||
evmasm::AssemblyItem::computeSourceMapping(
|
||||
assembly.items(),
|
||||
{{scanner().charStream() ? scanner().charStream()->name() : "", 0}}
|
||||
)
|
||||
);
|
||||
|
||||
MachineAssemblyObject runtimeObject;
|
||||
// Heuristic: If there is a single sub-assembly, this is likely the runtime object.
|
||||
if (assembly.numSubs() == 1)
|
||||
{
|
||||
evmasm::Assembly& runtimeAssembly = assembly.sub(0);
|
||||
runtimeObject.bytecode = make_shared<evmasm::LinkerObject>(runtimeAssembly.assemble());
|
||||
runtimeObject.assembly = runtimeAssembly.assemblyString();
|
||||
runtimeObject.sourceMappings = make_unique<string>(
|
||||
evmasm::AssemblyItem::computeSourceMapping(
|
||||
runtimeAssembly.items(),
|
||||
{{scanner().charStream() ? scanner().charStream()->name() : "", 0}}
|
||||
)
|
||||
);
|
||||
}
|
||||
return {std::move(creationObject), std::move(runtimeObject)};
|
||||
|
||||
}
|
||||
|
||||
string AssemblyStack::print() const
|
||||
{
|
||||
yulAssert(m_parserResult, "");
|
||||
|
@ -88,6 +88,12 @@ public:
|
||||
/// Run the assembly step (should only be called after parseAndAnalyze).
|
||||
MachineAssemblyObject assemble(Machine _machine) const;
|
||||
|
||||
/// Run the assembly step (should only be called after parseAndAnalyze).
|
||||
/// In addition to the value returned by @a assemble, returns
|
||||
/// a second object that is guessed to be the runtime code.
|
||||
/// Only available for EVM.
|
||||
std::pair<MachineAssemblyObject, MachineAssemblyObject> assembleAndGuessRuntime() const;
|
||||
|
||||
/// @returns the errors generated during parsing, analysis (and potentially assembly).
|
||||
langutil::ErrorList const& errors() const { return m_errors; }
|
||||
|
||||
|
@ -22,7 +22,7 @@ sub_0: assembly {
|
||||
/* \"A\":137:149 */
|
||||
revert
|
||||
}
|
||||
","bytecode":{"linkReferences":{},"object":"bytecode removed","opcodes":"opcodes removed","sourceMap":"sourceMap removed"}},"ir":"object \"NamedObject\" {
|
||||
","bytecode":{"linkReferences":{},"object":"bytecode removed","opcodes":"opcodes removed","sourceMap":"sourceMap removed"},"deployedBytecode":{"linkReferences":{},"object":"bytecode removed","opcodes":"opcodes removed","sourceMap":"sourceMap removed"}},"ir":"object \"NamedObject\" {
|
||||
code {
|
||||
let x := dataoffset(\"DataName\")
|
||||
sstore(add(x, 0), 0)
|
||||
|
Loading…
Reference in New Issue
Block a user