aboutsummaryrefslogtreecommitdiffstats
path: root/libsolidity/codegen/CompilerContext.cpp
diff options
context:
space:
mode:
authorchriseth <c@ethdev.com>2017-01-20 00:21:55 +0800
committerchriseth <c@ethdev.com>2017-01-24 19:06:40 +0800
commitb60623521f052b8a36c61f8632d868cac552bf29 (patch)
tree2d8b2bd51b3b052b89f17530e4e5399e40838d4d /libsolidity/codegen/CompilerContext.cpp
parentd0e8d340a53395de4c83e4e1d6ccf4c8eab5889a (diff)
downloaddexon-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.cpp69
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.");