From 79794081eb310f5c384261459980b1c8f60bee6e Mon Sep 17 00:00:00 2001 From: Alex Beregszaszi Date: Tue, 15 Jun 2021 14:48:59 +0100 Subject: [PATCH] Extract assemble() from compileContract() in CompilerStack --- libsolidity/interface/CompilerStack.cpp | 96 ++++++++++++++----------- libsolidity/interface/CompilerStack.h | 8 +++ 2 files changed, 63 insertions(+), 41 deletions(-) diff --git a/libsolidity/interface/CompilerStack.cpp b/libsolidity/interface/CompilerStack.cpp index 35e497f9a..bc6df3f83 100644 --- a/libsolidity/interface/CompilerStack.cpp +++ b/libsolidity/interface/CompilerStack.cpp @@ -1227,6 +1227,59 @@ bool onlySafeExperimentalFeaturesActivated(set const& featu } } +void CompilerStack::assemble( + ContractDefinition const& _contract, + std::shared_ptr _assembly, + std::shared_ptr _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>& _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) diff --git a/libsolidity/interface/CompilerStack.h b/libsolidity/interface/CompilerStack.h index 1a02fb226..a151af719 100644 --- a/libsolidity/interface/CompilerStack.h +++ b/libsolidity/interface/CompilerStack.h @@ -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 _assembly, + std::shared_ptr _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.