diff options
author | chriseth <chris@ethereum.org> | 2017-01-25 00:37:22 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-01-25 00:37:22 +0800 |
commit | 3dc83aa34e83d668cde82953f9efa94ebb7de8ed (patch) | |
tree | 06013ebd774f99584be9ca09c22feac010ebc2c7 /libsolidity/codegen/CompilerContext.cpp | |
parent | 29dab03ec8b595fc25e010bd8b60b2e280d0ebed (diff) | |
parent | 7e6f1b3f0008d03e6cdfa186b8f9976570865d4e (diff) | |
download | dexon-solidity-3dc83aa34e83d668cde82953f9efa94ebb7de8ed.tar dexon-solidity-3dc83aa34e83d668cde82953f9efa94ebb7de8ed.tar.gz dexon-solidity-3dc83aa34e83d668cde82953f9efa94ebb7de8ed.tar.bz2 dexon-solidity-3dc83aa34e83d668cde82953f9efa94ebb7de8ed.tar.lz dexon-solidity-3dc83aa34e83d668cde82953f9efa94ebb7de8ed.tar.xz dexon-solidity-3dc83aa34e83d668cde82953f9efa94ebb7de8ed.tar.zst dexon-solidity-3dc83aa34e83d668cde82953f9efa94ebb7de8ed.zip |
Merge pull request #1588 from ethereum/fixrecursivestructs
Introduce low-level functions
Diffstat (limited to 'libsolidity/codegen/CompilerContext.cpp')
-rw-r--r-- | libsolidity/codegen/CompilerContext.cpp | 54 |
1 files changed, 51 insertions, 3 deletions
diff --git a/libsolidity/codegen/CompilerContext.cpp b/libsolidity/codegen/CompilerContext.cpp index c14ab845..e26f96e8 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(int(_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) { |