diff options
author | Christian <c@ethdev.com> | 2015-02-11 00:53:43 +0800 |
---|---|---|
committer | Christian <c@ethdev.com> | 2015-02-12 18:33:10 +0800 |
commit | adb434569c7f54a12dfbdc674b50a4a4baca59e4 (patch) | |
tree | 5ac29b6c5a670de2458004c03337f6334b63ef2c /CompilerUtils.cpp | |
parent | 79aec95228f5c766daaa9d04a3800be99ded8015 (diff) | |
download | dexon-solidity-adb434569c7f54a12dfbdc674b50a4a4baca59e4.tar.gz dexon-solidity-adb434569c7f54a12dfbdc674b50a4a4baca59e4.tar.zst dexon-solidity-adb434569c7f54a12dfbdc674b50a4a4baca59e4.zip |
Dynamic copy to memory.
Diffstat (limited to 'CompilerUtils.cpp')
-rw-r--r-- | CompilerUtils.cpp | 41 |
1 files changed, 30 insertions, 11 deletions
diff --git a/CompilerUtils.cpp b/CompilerUtils.cpp index 3101c1b4..12940367 100644 --- a/CompilerUtils.cpp +++ b/CompilerUtils.cpp @@ -62,20 +62,22 @@ unsigned CompilerUtils::loadFromMemory(unsigned _offset, unsigned _bytes, bool _ } } -unsigned CompilerUtils::storeInMemory(unsigned _offset, unsigned _bytes, bool _leftAligned, - bool _padToWordBoundaries) +unsigned CompilerUtils::storeInMemory(unsigned _offset, Type const& _type, bool _padToWordBoundaries) { - if (_bytes == 0) + unsigned numBytes = prepareMemoryStore(_type, _padToWordBoundaries); + if (numBytes > 0) + m_context << u256(_offset) << eth::Instruction::MSTORE; + return numBytes; +} + +void CompilerUtils::storeInMemoryDynamic(Type const& _type, bool _padToWordBoundaries) +{ + unsigned numBytes = prepareMemoryStore(_type, _padToWordBoundaries); + if (numBytes > 0) { - m_context << eth::Instruction::POP; - return 0; + m_context << eth::Instruction::DUP2 << eth::Instruction::MSTORE; + m_context << u256(numBytes) << eth::Instruction::ADD; } - solAssert(_bytes <= 32, "Memory store of more than 32 bytes requested."); - if (_bytes != 32 && !_leftAligned && !_padToWordBoundaries) - // shift the value accordingly before storing - m_context << (u256(1) << ((32 - _bytes) * 8)) << eth::Instruction::MUL; - m_context << u256(_offset) << eth::Instruction::MSTORE; - return _padToWordBoundaries ? 32 : _bytes; } void CompilerUtils::moveToStackVariable(VariableDeclaration const& _variable) @@ -114,5 +116,22 @@ unsigned CompilerUtils::getSizeOnStack(vector<shared_ptr<Type const>> const& _va return size; } +unsigned CompilerUtils::prepareMemoryStore(Type const& _type, bool _padToWordBoundaries) +{ + unsigned _encodedSize = _type.getCalldataEncodedSize(); + unsigned numBytes = _padToWordBoundaries ? getPaddedSize(_encodedSize) : _encodedSize; + bool leftAligned = _type.getCategory() == Type::Category::String; + if (numBytes == 0) + m_context << eth::Instruction::POP; + else + { + solAssert(numBytes <= 32, "Memory store of more than 32 bytes requested."); + if (numBytes != 32 && !leftAligned && !_padToWordBoundaries) + // shift the value accordingly before storing + m_context << (u256(1) << ((32 - numBytes) * 8)) << eth::Instruction::MUL; + } + return numBytes; +} + } } |