Extract assemble() from compileContract() in CompilerStack

This commit is contained in:
Alex Beregszaszi 2021-06-15 14:48:59 +01:00 committed by chriseth
parent e0c2999e01
commit 79794081eb
2 changed files with 63 additions and 41 deletions

View File

@ -1227,6 +1227,59 @@ bool onlySafeExperimentalFeaturesActivated(set<ExperimentalFeature> const& featu
}
}
void CompilerStack::assemble(
ContractDefinition const& _contract,
std::shared_ptr<evmasm::Assembly> _assembly,
std::shared_ptr<evmasm::Assembly> _runtimeAssembly
)
{
solAssert(m_stackState >= AnalysisPerformed, "");
solAssert(!m_hasError, "");
Contract& compiledContract = m_contracts.at(_contract.fullyQualifiedName());
compiledContract.evmAssembly = _assembly;
solAssert(compiledContract.evmAssembly, "");
try
{
// Assemble deployment (incl. runtime) object.
compiledContract.object = compiledContract.evmAssembly->assemble();
}
catch (evmasm::AssemblyException const&)
{
solAssert(false, "Assembly exception for bytecode");
}
solAssert(compiledContract.object.immutableReferences.empty(), "Leftover immutables.");
compiledContract.evmRuntimeAssembly = _runtimeAssembly;
solAssert(compiledContract.evmRuntimeAssembly, "");
try
{
// Assemble runtime object.
compiledContract.runtimeObject = compiledContract.evmRuntimeAssembly->assemble();
}
catch (evmasm::AssemblyException const&)
{
solAssert(false, "Assembly exception for deployed bytecode");
}
// Throw a warning if EIP-170 limits are exceeded:
// If contract creation returns data with length greater than 0x6000 (214 + 213) bytes,
// contract creation fails with an out of gas error.
if (
m_evmVersion >= langutil::EVMVersion::spuriousDragon() &&
compiledContract.runtimeObject.bytecode.size() > 0x6000
)
m_errorReporter.warning(
5574_error,
_contract.location(),
"Contract code size exceeds 24576 bytes (a limit introduced in Spurious Dragon). "
"This contract may not be deployable on mainnet. "
"Consider enabling the optimizer (with a low \"runs\" value!), "
"turning off revert strings, or using libraries."
);
}
void CompilerStack::compileContract(
ContractDefinition const& _contract,
map<ContractDefinition const*, shared_ptr<Compiler const>>& _otherCompilers
@ -1262,48 +1315,9 @@ void CompilerStack::compileContract(
solAssert(false, "Optimizer exception during compilation");
}
compiledContract.evmAssembly = compiler->assemblyPtr();
solAssert(compiledContract.evmAssembly, "");
try
{
// Assemble deployment (incl. runtime) object.
compiledContract.object = compiledContract.evmAssembly->assemble();
}
catch(evmasm::AssemblyException const&)
{
solAssert(false, "Assembly exception for bytecode");
}
solAssert(compiledContract.object.immutableReferences.empty(), "Leftover immutables.");
compiledContract.evmRuntimeAssembly = compiler->runtimeAssemblyPtr();
solAssert(compiledContract.evmRuntimeAssembly, "");
try
{
// Assemble runtime object.
compiledContract.runtimeObject = compiledContract.evmRuntimeAssembly->assemble();
}
catch(evmasm::AssemblyException const&)
{
solAssert(false, "Assembly exception for deployed bytecode");
}
// Throw a warning if EIP-170 limits are exceeded:
// If contract creation returns data with length greater than 0x6000 (214 + 213) bytes,
// contract creation fails with an out of gas error.
if (
m_evmVersion >= langutil::EVMVersion::spuriousDragon() &&
compiledContract.runtimeObject.bytecode.size() > 0x6000
)
m_errorReporter.warning(
5574_error,
_contract.location(),
"Contract code size exceeds 24576 bytes (a limit introduced in Spurious Dragon). "
"This contract may not be deployable on mainnet. "
"Consider enabling the optimizer (with a low \"runs\" value!), "
"turning off revert strings, or using libraries."
);
_otherCompilers[compiledContract.contract] = compiler;
assemble(_contract, compiler->assemblyPtr(), compiler->runtimeAssemblyPtr());
}
void CompilerStack::generateIR(ContractDefinition const& _contract)

View File

@ -403,6 +403,14 @@ private:
/// @returns true if the contract is requested to be compiled.
bool isRequestedContract(ContractDefinition const& _contract) const;
/// Assembles the contract.
/// This function should only be internally called by compileContract and generateEVMFromIR.
void assemble(
ContractDefinition const& _contract,
std::shared_ptr<evmasm::Assembly> _assembly,
std::shared_ptr<evmasm::Assembly> _runtimeAssembly
);
/// Compile a single contract.
/// @param _otherCompilers provides access to compilers of other contracts, to get
/// their bytecode if needed. Only filled after they have been compiled.