aboutsummaryrefslogtreecommitdiffstats
path: root/CompilerUtils.cpp
diff options
context:
space:
mode:
authorChristian <c@ethdev.com>2015-02-11 00:53:43 +0800
committerChristian <c@ethdev.com>2015-02-12 18:33:10 +0800
commitadb434569c7f54a12dfbdc674b50a4a4baca59e4 (patch)
tree5ac29b6c5a670de2458004c03337f6334b63ef2c /CompilerUtils.cpp
parent79aec95228f5c766daaa9d04a3800be99ded8015 (diff)
downloaddexon-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.cpp41
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;
+}
+
}
}