Do not create a copy of the assembly.

This commit is contained in:
chriseth 2019-01-16 11:44:11 +01:00
parent a9fa2658d8
commit 29f6aa7d56
6 changed files with 22 additions and 14 deletions

View File

@ -47,6 +47,12 @@ void Compiler::compileContract(
m_context.optimise(m_optimize, m_optimizeRuns);
}
std::shared_ptr<eth::Assembly> Compiler::runtimeAssemblyPtr() const
{
solAssert(m_context.runtimeContext(), "");
return m_context.runtimeContext()->assemblyPtr();
}
eth::AssemblyItem Compiler::functionEntryLabel(FunctionDefinition const& _function) const
{
return m_runtimeContext.functionEntryLabelIfExists(_function);

View File

@ -50,8 +50,10 @@ public:
);
/// @returns Entire assembly.
eth::Assembly const& assembly() const { return m_context.assembly(); }
/// @returns Entire assembly as a shared pointer to non-const.
std::shared_ptr<eth::Assembly> assemblyPtr() const { return m_context.assemblyPtr(); }
/// @returns Runtime assembly.
eth::Assembly const& runtimeAssembly() const { return m_context.assembly().sub(m_runtimeSub); }
std::shared_ptr<eth::Assembly> runtimeAssemblyPtr() const;
/// @returns The entire assembled object (with constructor).
eth::LinkerObject assembledObject() const { return m_context.assembledObject(); }
/// @returns Only the runtime object (without constructor).

View File

@ -167,18 +167,18 @@ unsigned CompilerContext::numberOfLocalVariables() const
return m_localVariables.size();
}
eth::Assembly const& CompilerContext::compiledContract(ContractDefinition const& _contract) const
shared_ptr<eth::Assembly> CompilerContext::compiledContract(ContractDefinition const& _contract) const
{
auto ret = m_otherCompilers.find(&_contract);
solAssert(ret != m_otherCompilers.end(), "Compiled contract not found.");
return ret->second->assembly();
return ret->second->assemblyPtr();
}
eth::Assembly const& CompilerContext::compiledContractRuntime(ContractDefinition const& _contract) const
shared_ptr<eth::Assembly> CompilerContext::compiledContractRuntime(ContractDefinition const& _contract) const
{
auto ret = m_otherCompilers.find(&_contract);
solAssert(ret != m_otherCompilers.end(), "Compiled contract not found.");
return ret->second->runtimeAssembly();
return ret->second->runtimeAssemblyPtr();
}
bool CompilerContext::isLocalVariable(Declaration const* _declaration) const

View File

@ -76,8 +76,8 @@ public:
unsigned numberOfLocalVariables() const;
void setOtherCompilers(std::map<ContractDefinition const*, std::shared_ptr<Compiler const>> const& _otherCompilers) { m_otherCompilers = _otherCompilers; }
eth::Assembly const& compiledContract(ContractDefinition const& _contract) const;
eth::Assembly const& compiledContractRuntime(ContractDefinition const& _contract) const;
std::shared_ptr<eth::Assembly> compiledContract(ContractDefinition const& _contract) const;
std::shared_ptr<eth::Assembly> compiledContractRuntime(ContractDefinition const& _contract) const;
void setStackOffset(int _offset) { m_asm->setDeposit(_offset); }
void adjustStackOffset(int _adjustment) { m_asm->adjustDeposit(_adjustment); }
@ -224,15 +224,15 @@ public:
void optimise(bool _fullOptimsation, unsigned _runs = 200) { m_asm->optimise(_fullOptimsation, m_evmVersion, true, _runs); }
/// @returns the runtime context if in creation mode and runtime context is set, nullptr otherwise.
CompilerContext* runtimeContext() { return m_runtimeContext; }
CompilerContext* runtimeContext() const { return m_runtimeContext; }
/// @returns the identifier of the runtime subroutine.
size_t runtimeSub() const { return m_runtimeSub; }
/// @returns a const reference to the underlying assembly.
eth::Assembly const& assembly() const { return *m_asm; }
/// @returns non-const reference to the underlying assembly. Should be avoided in favour of
/// wrappers in this class.
eth::Assembly& nonConstAssembly() { return *m_asm; }
/// @returns a shared pointer to the assembly.
/// Should be avoided except when adding sub-assemblies.
std::shared_ptr<eth::Assembly> assemblyPtr() const { return m_asm; }
/// @arg _sourceCodes is the map of input files to source code strings
std::string assemblyString(StringMap const& _sourceCodes = StringMap()) const

View File

@ -1209,12 +1209,12 @@ void CompilerUtils::copyContractCodeToMemory(ContractDefinition const& contract,
[&contract, _creation](CompilerContext& _context)
{
// copy the contract's code into memory
eth::Assembly const& assembly =
shared_ptr<eth::Assembly> assembly =
_creation ?
_context.compiledContract(contract) :
_context.compiledContractRuntime(contract);
// pushes size
auto subroutine = _context.addSubroutine(make_shared<eth::Assembly>(assembly));
auto subroutine = _context.addSubroutine(assembly);
_context << Instruction::DUP1 << subroutine;
_context << Instruction::DUP4 << Instruction::CODECOPY;
_context << Instruction::ADD;

View File

@ -716,7 +716,7 @@ bool ContractCompiler::visit(InlineAssembly const& _inlineAssembly)
CodeGenerator::assemble(
_inlineAssembly.operations(),
*_inlineAssembly.annotation().analysisInfo,
m_context.nonConstAssembly(),
*m_context.assemblyPtr(),
identifierAccess
);
m_context.setStackOffset(startStackHeight);