diff options
author | Gav Wood <i@gavwood.com> | 2015-02-21 04:56:37 +0800 |
---|---|---|
committer | Gav Wood <i@gavwood.com> | 2015-02-21 04:56:37 +0800 |
commit | 89d84edb16812ff9e4b1049ee0257d65c75f5a3c (patch) | |
tree | baeda13e44a8fc0f6ac2f705fdf334da14405f39 /CompilerContext.cpp | |
parent | d552ceb50f8e3888abf5b9a6095a5fb60ee91b5f (diff) | |
parent | 852405116654bda9f4dc1d4876a2368184b30a8c (diff) | |
download | dexon-solidity-89d84edb16812ff9e4b1049ee0257d65c75f5a3c.tar dexon-solidity-89d84edb16812ff9e4b1049ee0257d65c75f5a3c.tar.gz dexon-solidity-89d84edb16812ff9e4b1049ee0257d65c75f5a3c.tar.bz2 dexon-solidity-89d84edb16812ff9e4b1049ee0257d65c75f5a3c.tar.lz dexon-solidity-89d84edb16812ff9e4b1049ee0257d65c75f5a3c.tar.xz dexon-solidity-89d84edb16812ff9e4b1049ee0257d65c75f5a3c.tar.zst dexon-solidity-89d84edb16812ff9e4b1049ee0257d65c75f5a3c.zip |
Merge branch 'develop'
Conflicts:
README.md
evmjit
libdevcrypto/CryptoPP.cpp
libethereum/State.cpp
neth/main.cpp
Diffstat (limited to 'CompilerContext.cpp')
-rw-r--r-- | CompilerContext.cpp | 95 |
1 files changed, 77 insertions, 18 deletions
diff --git a/CompilerContext.cpp b/CompilerContext.cpp index 18357bf0..01a71d7c 100644 --- a/CompilerContext.cpp +++ b/CompilerContext.cpp @@ -43,25 +43,28 @@ void CompilerContext::addStateVariable(VariableDeclaration const& _declaration) m_stateVariablesSize += _declaration.getType()->getStorageSize(); } -void CompilerContext::addVariable(VariableDeclaration const& _declaration) +void CompilerContext::startFunction(Declaration const& _function) { - m_localVariables[&_declaration] = m_localVariablesSize; - m_localVariablesSize += _declaration.getType()->getSizeOnStack(); + m_functionsWithCode.insert(&_function); + m_localVariables.clear(); + m_asm.setDeposit(0); + *this << getFunctionEntryLabel(_function); +} + +void CompilerContext::addVariable(VariableDeclaration const& _declaration, + unsigned _offsetToCurrent) +{ + solAssert(m_asm.deposit() >= 0 && unsigned(m_asm.deposit()) >= _offsetToCurrent, ""); + m_localVariables[&_declaration] = unsigned(m_asm.deposit()) - _offsetToCurrent; } void CompilerContext::addAndInitializeVariable(VariableDeclaration const& _declaration) { addVariable(_declaration); - unsigned const size = _declaration.getType()->getSizeOnStack(); - for (unsigned i = 0; i < size; ++i) + int const size = _declaration.getType()->getSizeOnStack(); + for (int i = 0; i < size; ++i) *this << u256(0); - m_asm.adjustDeposit(-size); -} - -void CompilerContext::addFunction(FunctionDefinition const& _function) -{ - m_functionEntryLabels.insert(std::make_pair(&_function, m_asm.newTag())); } bytes const& CompilerContext::getCompiledContract(const ContractDefinition& _contract) const @@ -73,26 +76,82 @@ bytes const& CompilerContext::getCompiledContract(const ContractDefinition& _con bool CompilerContext::isLocalVariable(Declaration const* _declaration) const { - return m_localVariables.count(_declaration) > 0; + return !!m_localVariables.count(_declaration); } -eth::AssemblyItem CompilerContext::getFunctionEntryLabel(FunctionDefinition const& _function) const +eth::AssemblyItem CompilerContext::getFunctionEntryLabel(Declaration const& _declaration) { - auto res = m_functionEntryLabels.find(&_function); - solAssert(res != m_functionEntryLabels.end(), "Function entry label not found."); - return res->second.tag(); + auto res = m_functionEntryLabels.find(&_declaration); + if (res == m_functionEntryLabels.end()) + { + eth::AssemblyItem tag(m_asm.newTag()); + m_functionEntryLabels.insert(make_pair(&_declaration, tag)); + return tag.tag(); + } + else + return res->second.tag(); +} + +eth::AssemblyItem CompilerContext::getVirtualFunctionEntryLabel(FunctionDefinition const& _function) +{ + solAssert(!m_inheritanceHierarchy.empty(), "No inheritance hierarchy set."); + for (ContractDefinition const* contract: m_inheritanceHierarchy) + for (ASTPointer<FunctionDefinition> const& function: contract->getDefinedFunctions()) + if (!function->isConstructor() && function->getName() == _function.getName()) + return getFunctionEntryLabel(*function); + solAssert(false, "Virtual function " + _function.getName() + " not found."); + return m_asm.newTag(); // not reached +} + +eth::AssemblyItem CompilerContext::getSuperFunctionEntryLabel(string const& _name, ContractDefinition const& _base) +{ + // search for first contract after _base + solAssert(!m_inheritanceHierarchy.empty(), "No inheritance hierarchy set."); + auto it = find(m_inheritanceHierarchy.begin(), m_inheritanceHierarchy.end(), &_base); + solAssert(it != m_inheritanceHierarchy.end(), "Base not found in inheritance hierarchy."); + for (++it; it != m_inheritanceHierarchy.end(); ++it) + for (ASTPointer<FunctionDefinition> const& function: (*it)->getDefinedFunctions()) + if (!function->isConstructor() && function->getName() == _name) + return getFunctionEntryLabel(*function); + solAssert(false, "Super function " + _name + " not found."); + return m_asm.newTag(); // not reached +} + +set<Declaration const*> CompilerContext::getFunctionsWithoutCode() +{ + set<Declaration const*> functions; + for (auto const& it: m_functionEntryLabels) + if (m_functionsWithCode.count(it.first) == 0) + functions.insert(it.first); + return move(functions); +} + +ModifierDefinition const& CompilerContext::getFunctionModifier(string const& _name) const +{ + solAssert(!m_inheritanceHierarchy.empty(), "No inheritance hierarchy set."); + for (ContractDefinition const* contract: m_inheritanceHierarchy) + for (ASTPointer<ModifierDefinition> const& modifier: contract->getFunctionModifiers()) + if (modifier->getName() == _name) + return *modifier.get(); + BOOST_THROW_EXCEPTION(InternalCompilerError() + << errinfo_comment("Function modifier " + _name + " not found.")); } unsigned CompilerContext::getBaseStackOffsetOfVariable(Declaration const& _declaration) const { auto res = m_localVariables.find(&_declaration); solAssert(res != m_localVariables.end(), "Variable not found on stack."); - return m_localVariablesSize - res->second - 1; + return res->second; } unsigned CompilerContext::baseToCurrentStackOffset(unsigned _baseOffset) const { - return _baseOffset + m_asm.deposit(); + return m_asm.deposit() - _baseOffset - 1; +} + +unsigned CompilerContext::currentToBaseStackOffset(unsigned _offset) const +{ + return m_asm.deposit() - _offset - 1; } u256 CompilerContext::getStorageLocationOfVariable(const Declaration& _declaration) const |