aboutsummaryrefslogtreecommitdiffstats
path: root/ArrayUtils.cpp
diff options
context:
space:
mode:
authorchriseth <c@ethdev.com>2015-06-27 02:27:56 +0800
committerchriseth <c@ethdev.com>2015-06-27 02:27:56 +0800
commit109b4eafb9d543abb13ed24055bd71d4f67cb9ec (patch)
treed3ef61cf7f896d36b40a176d8caa2b8c7ceb5e2f /ArrayUtils.cpp
parent37e7f1f10d597efb7773417779e32f0533b6ba1b (diff)
downloaddexon-solidity-109b4eafb9d543abb13ed24055bd71d4f67cb9ec.tar
dexon-solidity-109b4eafb9d543abb13ed24055bd71d4f67cb9ec.tar.gz
dexon-solidity-109b4eafb9d543abb13ed24055bd71d4f67cb9ec.tar.bz2
dexon-solidity-109b4eafb9d543abb13ed24055bd71d4f67cb9ec.tar.lz
dexon-solidity-109b4eafb9d543abb13ed24055bd71d4f67cb9ec.tar.xz
dexon-solidity-109b4eafb9d543abb13ed24055bd71d4f67cb9ec.tar.zst
dexon-solidity-109b4eafb9d543abb13ed24055bd71d4f67cb9ec.zip
Some fixes for calldata arrays.
Diffstat (limited to 'ArrayUtils.cpp')
-rw-r--r--ArrayUtils.cpp27
1 files changed, 16 insertions, 11 deletions
diff --git a/ArrayUtils.cpp b/ArrayUtils.cpp
index 74bde70a..f13b2817 100644
--- a/ArrayUtils.cpp
+++ b/ArrayUtils.cpp
@@ -39,11 +39,6 @@ void ArrayUtils::copyArrayToStorage(ArrayType const& _targetType, ArrayType cons
// stack layout: [source_ref] [source_byte_off] [source length] target_ref target_byte_off (top)
solAssert(_targetType.location() == DataLocation::Storage, "");
- if (_sourceType.location() == DataLocation::Memory)
- solAssert(
- _sourceType.getBaseType()->isValueType(),
- "Copying arrays of non-value-types to storage not yet implemented."
- );
IntegerType uint256(256);
Type const* targetBaseType = _targetType.isByteArray() ? &uint256 : &(*_targetType.getBaseType());
@@ -139,14 +134,14 @@ void ArrayUtils::copyArrayToStorage(ArrayType const& _targetType, ArrayType cons
if (sourceBaseType->getCategory() == Type::Category::Array)
{
solAssert(byteOffsetSize == 0, "Byte offset for array as base type.");
+ auto const& sourceBaseArrayType = dynamic_cast<ArrayType const&>(*sourceBaseType);
m_context << eth::Instruction::DUP3;
if (sourceIsStorage)
m_context << u256(0);
+ else if (sourceBaseArrayType.location() == DataLocation::Memory)
+ m_context << eth::Instruction::MLOAD;
m_context << eth::dupInstruction(sourceIsStorage ? 4 : 3) << u256(0);
- copyArrayToStorage(
- dynamic_cast<ArrayType const&>(*targetBaseType),
- dynamic_cast<ArrayType const&>(*sourceBaseType)
- );
+ copyArrayToStorage(dynamic_cast<ArrayType const&>(*targetBaseType), sourceBaseArrayType);
m_context << eth::Instruction::POP << eth::Instruction::POP;
}
else if (directCopy)
@@ -193,11 +188,18 @@ void ArrayUtils::copyArrayToStorage(ArrayType const& _targetType, ArrayType cons
if (haveByteOffsetSource)
incrementByteOffset(sourceBaseType->getStorageBytes(), 1, haveByteOffsetTarget ? 5 : 4);
else
+ {
+ m_context << eth::swapInstruction(2 + byteOffsetSize);
+ if (sourceIsStorage)
+ m_context << sourceBaseType->getStorageSize();
+ else if (_sourceType.location() == DataLocation::Memory)
+ m_context << sourceBaseType->memoryHeadSize();
+ else
+ m_context << sourceBaseType->getCalldataEncodedSize(true);
m_context
- << eth::swapInstruction(2 + byteOffsetSize)
- << (sourceIsStorage ? sourceBaseType->getStorageSize() : sourceBaseType->getCalldataEncodedSize())
<< eth::Instruction::ADD
<< eth::swapInstruction(2 + byteOffsetSize);
+ }
// increment target
if (haveByteOffsetTarget)
incrementByteOffset(targetBaseType->getStorageBytes(), byteOffsetSize, byteOffsetSize + 2);
@@ -696,6 +698,9 @@ void ArrayUtils::accessIndex(ArrayType const& _arrayType, bool _doBoundsCheck) c
// out-of-bounds access throws exception
m_context.appendConditionalJumpTo(m_context.errorTag());
}
+ else if (location == DataLocation::CallData && _arrayType.isDynamicallySized())
+ // remove length if present
+ m_context << eth::Instruction::SWAP1 << eth::Instruction::POP;
// stack: <base_ref> <index>
m_context << eth::Instruction::SWAP1;