diff options
author | chriseth <c@ethdev.com> | 2015-12-01 00:32:54 +0800 |
---|---|---|
committer | chriseth <c@ethdev.com> | 2015-12-01 01:50:47 +0800 |
commit | 35b310cfaf1d44aba8d12f15a528e49ac5a1997d (patch) | |
tree | b41d2144ec9f1f3704149a90ef69e36404089a0c /libsolidity | |
parent | e9c7837c154482a72c8519fbdc9376693ce9a1d5 (diff) | |
download | dexon-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.cpp | 29 | ||||
-rw-r--r-- | libsolidity/codegen/CompilerUtils.h | 6 |
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. |