aboutsummaryrefslogtreecommitdiffstats
path: root/CompilerContext.cpp
diff options
context:
space:
mode:
authorGav Wood <i@gavwood.com>2015-02-21 04:56:37 +0800
committerGav Wood <i@gavwood.com>2015-02-21 04:56:37 +0800
commit89d84edb16812ff9e4b1049ee0257d65c75f5a3c (patch)
treebaeda13e44a8fc0f6ac2f705fdf334da14405f39 /CompilerContext.cpp
parentd552ceb50f8e3888abf5b9a6095a5fb60ee91b5f (diff)
parent852405116654bda9f4dc1d4876a2368184b30a8c (diff)
downloaddexon-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.cpp95
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