aboutsummaryrefslogtreecommitdiffstats
path: root/libsolidity/codegen/CompilerContext.cpp
diff options
context:
space:
mode:
authorchriseth <chris@ethereum.org>2017-01-25 00:37:22 +0800
committerGitHub <noreply@github.com>2017-01-25 00:37:22 +0800
commit3dc83aa34e83d668cde82953f9efa94ebb7de8ed (patch)
tree06013ebd774f99584be9ca09c22feac010ebc2c7 /libsolidity/codegen/CompilerContext.cpp
parent29dab03ec8b595fc25e010bd8b60b2e280d0ebed (diff)
parent7e6f1b3f0008d03e6cdfa186b8f9976570865d4e (diff)
downloaddexon-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.cpp54
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)
{