aboutsummaryrefslogtreecommitdiffstats
path: root/libsolidity
diff options
context:
space:
mode:
authorchriseth <c@ethdev.com>2015-12-01 00:32:54 +0800
committerchriseth <c@ethdev.com>2015-12-01 01:50:47 +0800
commit35b310cfaf1d44aba8d12f15a528e49ac5a1997d (patch)
treeb41d2144ec9f1f3704149a90ef69e36404089a0c /libsolidity
parente9c7837c154482a72c8519fbdc9376693ce9a1d5 (diff)
downloaddexon-solidity-35b310cfaf1d44aba8d12f15a528e49ac5a1997d.tar.gz
dexon-solidity-35b310cfaf1d44aba8d12f15a528e49ac5a1997d.tar.zst
dexon-solidity-35b310cfaf1d44aba8d12f15a528e49ac5a1997d.zip
Simplify and optimise stack rotation.
Diffstat (limited to 'libsolidity')
-rw-r--r--libsolidity/codegen/CompilerUtils.cpp29
-rw-r--r--libsolidity/codegen/CompilerUtils.h6
2 files changed, 27 insertions, 8 deletions
diff --git a/libsolidity/codegen/CompilerUtils.cpp b/libsolidity/codegen/CompilerUtils.cpp
index b57f5b29..bd0857f6 100644
--- a/libsolidity/codegen/CompilerUtils.cpp
+++ b/libsolidity/codegen/CompilerUtils.cpp
@@ -695,18 +695,31 @@ void CompilerUtils::copyToStackTop(unsigned _stackDepth, unsigned _itemSize)
void CompilerUtils::moveToStackTop(unsigned _stackDepth, unsigned _itemSize)
{
- solAssert(_stackDepth <= 15, "Stack too deep, try removing local variables.");
- for (unsigned j = 0; j < _itemSize; ++j)
- for (unsigned i = 0; i < _stackDepth + _itemSize - 1; ++i)
- m_context << eth::swapInstruction(1 + i);
+ moveIntoStack(_itemSize, _stackDepth);
}
void CompilerUtils::moveIntoStack(unsigned _stackDepth, unsigned _itemSize)
{
- solAssert(_stackDepth <= 16, "Stack too deep, try removing local variables.");
- for (unsigned j = 0; j < _itemSize; ++j)
- for (unsigned i = _stackDepth; i > 0; --i)
- m_context << eth::swapInstruction(i + _itemSize - 1);
+ if (_stackDepth <= _itemSize)
+ for (unsigned i = 0; i < _stackDepth; ++i)
+ rotateStackDown(_stackDepth + _itemSize);
+ else
+ for (unsigned i = 0; i < _itemSize; ++i)
+ rotateStackUp(_stackDepth + _itemSize);
+}
+
+void CompilerUtils::rotateStackUp(unsigned _items)
+{
+ solAssert(_items - 1 <= 16, "Stack too deep, try removing local variables.");
+ for (unsigned i = 1; i < _items; ++i)
+ m_context << eth::swapInstruction(_items - i);
+}
+
+void CompilerUtils::rotateStackDown(unsigned _items)
+{
+ solAssert(_items - 1 <= 16, "Stack too deep, try removing local variables.");
+ for (unsigned i = 1; i < _items; ++i)
+ m_context << eth::swapInstruction(i);
}
void CompilerUtils::popStackElement(Type const& _type)
diff --git a/libsolidity/codegen/CompilerUtils.h b/libsolidity/codegen/CompilerUtils.h
index 134afd78..55254013 100644
--- a/libsolidity/codegen/CompilerUtils.h
+++ b/libsolidity/codegen/CompilerUtils.h
@@ -134,6 +134,12 @@ public:
void moveToStackTop(unsigned _stackDepth, unsigned _itemSize = 1);
/// Moves @a _itemSize elements past @a _stackDepth other stack elements
void moveIntoStack(unsigned _stackDepth, unsigned _itemSize = 1);
+ /// Rotates the topmost @a _items items on the stack, such that the previously topmost element
+ /// is bottom-most.
+ void rotateStackUp(unsigned _items);
+ /// Rotates the topmost @a _items items on the stack, such that the previously bottom-most element
+ /// is now topmost.
+ void rotateStackDown(unsigned _items);
/// Removes the current value from the top of the stack.
void popStackElement(Type const& _type);
/// Removes element from the top of the stack _amount times.