aboutsummaryrefslogtreecommitdiffstats
path: root/ArrayUtils.cpp
diff options
context:
space:
mode:
authorChristian <c@ethdev.com>2015-03-04 00:55:28 +0800
committerchriseth <c@ethdev.com>2015-03-05 20:19:59 +0800
commitb84cf62d6bd3a9caa8a9a7f1dcd427418170aed9 (patch)
treec775f78562d5775487ba8b884d0499023734a7db /ArrayUtils.cpp
parenta4d772315d814408c057a9473c2c1fefa351a5b4 (diff)
downloaddexon-solidity-b84cf62d6bd3a9caa8a9a7f1dcd427418170aed9.tar.gz
dexon-solidity-b84cf62d6bd3a9caa8a9a7f1dcd427418170aed9.tar.zst
dexon-solidity-b84cf62d6bd3a9caa8a9a7f1dcd427418170aed9.zip
Index access for calldata arrays.
Diffstat (limited to 'ArrayUtils.cpp')
-rw-r--r--ArrayUtils.cpp39
1 files changed, 29 insertions, 10 deletions
diff --git a/ArrayUtils.cpp b/ArrayUtils.cpp
index 43cc6fd4..0dea5345 100644
--- a/ArrayUtils.cpp
+++ b/ArrayUtils.cpp
@@ -70,22 +70,25 @@ void ArrayUtils::copyArrayToStorage(ArrayType const& _targetType, ArrayType cons
m_context << eth::Instruction::ISZERO;
eth::AssemblyItem copyLoopEnd = m_context.newTag();
m_context.appendConditionalJumpTo(copyLoopEnd);
+ // add length to source offset
+ m_context << eth::Instruction::DUP5 << eth::Instruction::DUP5 << eth::Instruction::ADD;
+ // stack now: source_offset source_len target_ref target_data_end target_data_ref source_end
// store start offset
- m_context << eth::Instruction::DUP5;
- // stack now: source_offset source_len target_ref target_data_end target_data_ref calldata_offset
+ m_context << eth::Instruction::DUP6;
+ // stack now: source_offset source_len target_ref target_data_end target_data_ref source_end calldata_offset
eth::AssemblyItem copyLoopStart = m_context.newTag();
m_context << copyLoopStart
// copy from calldata and store
<< eth::Instruction::DUP1 << eth::Instruction::CALLDATALOAD
- << eth::Instruction::DUP3 << eth::Instruction::SSTORE
+ << eth::Instruction::DUP4 << eth::Instruction::SSTORE
// increment target_data_ref by 1
- << eth::Instruction::SWAP1 << u256(1) << eth::Instruction::ADD
+ << eth::Instruction::SWAP2 << u256(1) << eth::Instruction::ADD
// increment calldata_offset by 32
- << eth::Instruction::SWAP1 << u256(32) << eth::Instruction::ADD
+ << eth::Instruction::SWAP2 << u256(32) << eth::Instruction::ADD
// check for loop condition
- << eth::Instruction::DUP1 << eth::Instruction::DUP6 << eth::Instruction::GT;
+ << eth::Instruction::DUP1 << eth::Instruction::DUP3 << eth::Instruction::GT;
m_context.appendConditionalJumpTo(copyLoopStart);
- m_context << eth::Instruction::POP;
+ m_context << eth::Instruction::POP << eth::Instruction::POP;
m_context << copyLoopEnd;
// now clear leftover bytes of the old value
@@ -179,6 +182,7 @@ void ArrayUtils::clearArray(ArrayType const& _type) const
m_context << eth::Instruction::POP;
else if (_type.getLength() < 5) // unroll loop for small arrays @todo choose a good value
{
+ solAssert(!_type.isByteArray(), "");
for (unsigned i = 1; i < _type.getLength(); ++i)
{
StorageItem(m_context, *_type.getBaseType()).setToZero(SourceLocation(), false);
@@ -188,6 +192,7 @@ void ArrayUtils::clearArray(ArrayType const& _type) const
}
else
{
+ solAssert(!_type.isByteArray(), "");
m_context
<< eth::Instruction::DUP1 << u256(_type.getLength())
<< u256(_type.getBaseType()->getStorageSize())
@@ -296,9 +301,23 @@ void ArrayUtils::convertLengthToSize(ArrayType const& _arrayType) const
void ArrayUtils::retrieveLength(ArrayType const& _arrayType) const
{
- if (_arrayType.isDynamicallySized())
- m_context << eth::Instruction::DUP1 << eth::Instruction::SLOAD;
- else
+ if (!_arrayType.isDynamicallySized())
m_context << _arrayType.getLength();
+ else
+ {
+ m_context << eth::Instruction::DUP1;
+ switch (_arrayType.getLocation())
+ {
+ case ArrayType::Location::CallData:
+ // length is stored on the stack
+ break;
+ case ArrayType::Location::Memory:
+ m_context << eth::Instruction::MLOAD;
+ break;
+ case ArrayType::Location::Storage:
+ m_context << eth::Instruction::SLOAD;
+ break;
+ }
+ }
}