diff options
author | chriseth <c@ethdev.com> | 2017-01-20 00:21:55 +0800 |
---|---|---|
committer | chriseth <c@ethdev.com> | 2017-01-24 19:06:40 +0800 |
commit | b60623521f052b8a36c61f8632d868cac552bf29 (patch) | |
tree | 2d8b2bd51b3b052b89f17530e4e5399e40838d4d /libsolidity/codegen/CompilerContext.cpp | |
parent | d0e8d340a53395de4c83e4e1d6ccf4c8eab5889a (diff) | |
download | dexon-solidity-b60623521f052b8a36c61f8632d868cac552bf29.tar.gz dexon-solidity-b60623521f052b8a36c61f8632d868cac552bf29.tar.zst dexon-solidity-b60623521f052b8a36c61f8632d868cac552bf29.zip |
Move some util functions to low-level functions.
Diffstat (limited to 'libsolidity/codegen/CompilerContext.cpp')
-rw-r--r-- | libsolidity/codegen/CompilerContext.cpp | 69 |
1 files changed, 51 insertions, 18 deletions
diff --git a/libsolidity/codegen/CompilerContext.cpp b/libsolidity/codegen/CompilerContext.cpp index fcd39b33..dad227c7 100644 --- a/libsolidity/codegen/CompilerContext.cpp +++ b/libsolidity/codegen/CompilerContext.cpp @@ -21,15 +21,18 @@ */ #include <libsolidity/codegen/CompilerContext.h> -#include <utility> -#include <numeric> -#include <boost/algorithm/string/replace.hpp> +#include <libsolidity/codegen/CompilerUtils.h> #include <libsolidity/ast/AST.h> #include <libsolidity/codegen/Compiler.h> #include <libsolidity/interface/Version.h> #include <libsolidity/inlineasm/AsmData.h> #include <libsolidity/inlineasm/AsmStack.h> +#include <boost/algorithm/string/replace.hpp> + +#include <utility> +#include <numeric> + using namespace std; namespace dev @@ -57,6 +60,51 @@ void CompilerContext::startFunction(Declaration const& _function) *this << functionEntryLabel(_function); } +void CompilerContext::callLowLevelFunction( + string const& _name, + unsigned _inArgs, + unsigned _outArgs, + function<void(CompilerContext&)> const& _generator +) +{ + eth::AssemblyItem retTag = pushNewTag(); + CompilerUtils(*this).moveIntoStack(_inArgs); + + auto it = m_lowLevelFunctions.find(_name); + if (it == m_lowLevelFunctions.end()) + { + eth::AssemblyItem tag = newTag().pushTag(); + m_lowLevelFunctions.insert(make_pair(_name, tag)); + m_lowLevelFunctionGenerationQueue.push(make_tuple(_name, _inArgs, _outArgs, _generator)); + *this << tag; + } + else + *this << it->second; + appendJump(eth::AssemblyItem::JumpType::IntoFunction); + adjustStackOffset(_outArgs - 1 - _inArgs); + *this << retTag.tag(); +} + +void CompilerContext::appendMissingLowLevelFunctions() +{ + while (!m_lowLevelFunctionGenerationQueue.empty()) + { + string name; + unsigned inArgs; + unsigned outArgs; + function<void(CompilerContext&)> generator; + tie(name, inArgs, outArgs, generator) = m_lowLevelFunctionGenerationQueue.front(); + m_lowLevelFunctionGenerationQueue.pop(); + + setStackOffset(inArgs + 1); + *this << m_lowLevelFunctions.at(name).tag(); + generator(*this); + CompilerUtils(*this).moveToStackTop(outArgs); + appendJump(eth::AssemblyItem::JumpType::OutOfFunction); + solAssert(stackHeight() == outArgs, "Invalid stack height in low-level function " + name + "."); + } +} + void CompilerContext::addVariable(VariableDeclaration const& _declaration, unsigned _offsetToCurrent) { @@ -125,21 +173,6 @@ Declaration const* CompilerContext::nextFunctionToCompile() const return m_functionCompilationQueue.nextFunctionToCompile(); } -eth::AssemblyItem const* CompilerContext::lowLevelFunctionEntryPoint(string const& _name) const -{ - auto it = m_lowLevelFunctions.find(_name); - if (it == m_lowLevelFunctions.end()) - return nullptr; - else - return *it; -} - -void CompilerContext::addLowLevelFunction(string const& _name, eth::AssemblyItem const& _label) -{ - solAssert(lowLevelFunctionEntryPoint(_name) != nullptr, "Low level function with that name already exists."); - m_lowLevelFunctions[_name] = _label.pushTag(); -} - ModifierDefinition const& CompilerContext::functionModifier(string const& _name) const { solAssert(!m_inheritanceHierarchy.empty(), "No inheritance hierarchy set."); |