aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorchriseth <c@ethdev.com>2015-06-22 18:50:09 +0800
committerchriseth <c@ethdev.com>2015-06-23 02:50:47 +0800
commit2eabaa4716997242856b0e33bbc34a4d7204c301 (patch)
tree963d6aa6d25bc5df68075c0858e7fc36691a9198
parentee520f602263ba0fc70d51f3317d98a59e115ae3 (diff)
downloaddexon-solidity-2eabaa4716997242856b0e33bbc34a4d7204c301.tar
dexon-solidity-2eabaa4716997242856b0e33bbc34a4d7204c301.tar.gz
dexon-solidity-2eabaa4716997242856b0e33bbc34a4d7204c301.tar.bz2
dexon-solidity-2eabaa4716997242856b0e33bbc34a4d7204c301.tar.lz
dexon-solidity-2eabaa4716997242856b0e33bbc34a4d7204c301.tar.xz
dexon-solidity-2eabaa4716997242856b0e33bbc34a4d7204c301.tar.zst
dexon-solidity-2eabaa4716997242856b0e33bbc34a4d7204c301.zip
Memory-storage copy.
-rw-r--r--ArrayUtils.cpp26
-rw-r--r--ExpressionCompiler.cpp4
2 files changed, 18 insertions, 12 deletions
diff --git a/ArrayUtils.cpp b/ArrayUtils.cpp
index 43ffff0b..e138e951 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, "");
- solAssert(
- _sourceType.location() == DataLocation::CallData ||
- _sourceType.location() == DataLocation::Storage,
- "Given array location not implemented."
- );
IntegerType uint256(256);
Type const* targetBaseType = _targetType.isByteArray() ? &uint256 : &(*_targetType.getBaseType());
@@ -52,6 +47,7 @@ void ArrayUtils::copyArrayToStorage(ArrayType const& _targetType, ArrayType cons
// TODO unroll loop for small sizes
bool sourceIsStorage = _sourceType.location() == DataLocation::Storage;
+ bool fromCalldata = _sourceType.location() == DataLocation::CallData;
bool directCopy = sourceIsStorage && sourceBaseType->isValueType() && *sourceBaseType == *targetBaseType;
bool haveByteOffsetSource = !directCopy && sourceIsStorage && sourceBaseType->getStorageBytes() <= 16;
bool haveByteOffsetTarget = !directCopy && targetBaseType->getStorageBytes() <= 16;
@@ -71,6 +67,13 @@ void ArrayUtils::copyArrayToStorage(ArrayType const& _targetType, ArrayType cons
// retrieve source length
if (_sourceType.location() != DataLocation::CallData || !_sourceType.isDynamicallySized())
retrieveLength(_sourceType); // otherwise, length is already there
+ if (_sourceType.location() == DataLocation::Memory && _sourceType.isDynamicallySized())
+ {
+ // increment source pointer to point to data
+ m_context << eth::Instruction::SWAP1 << u256(0x20);
+ m_context << eth::Instruction::ADD << eth::Instruction::SWAP1;
+ }
+
// stack: target_ref source_ref source_length
m_context << eth::Instruction::DUP3;
// stack: target_ref source_ref source_length target_ref
@@ -164,9 +167,9 @@ void ArrayUtils::copyArrayToStorage(ArrayType const& _targetType, ArrayType cons
StorageItem(m_context, *sourceBaseType).retrieveValue(SourceLocation(), true);
}
else if (sourceBaseType->isValueType())
- CompilerUtils(m_context).loadFromMemoryDynamic(*sourceBaseType, true, true, false);
+ CompilerUtils(m_context).loadFromMemoryDynamic(*sourceBaseType, fromCalldata, true, false);
else
- solAssert(false, "Copying of unknown type requested: " + sourceBaseType->toString());
+ solAssert(false, "Copying of type " + _sourceType.toString(false) + " to storage not yet supported.");
// stack: target_ref target_data_end source_data_pos target_data_pos source_data_end [target_byte_offset] [source_byte_offset] <source_value>...
solAssert(
2 + byteOffsetSize + sourceBaseType->getSizeOnStack() <= 16,
@@ -419,6 +422,10 @@ void ArrayUtils::convertLengthToSize(ArrayType const& _arrayType, bool _pad) con
}
else
{
+ solAssert(
+ _arrayType.getBaseType()->getCalldataEncodedSize() > 0,
+ "Copying nested dynamic arrays not yet implemented."
+ );
if (!_arrayType.isByteArray())
m_context << _arrayType.getBaseType()->getCalldataEncodedSize() << eth::Instruction::MUL;
else if (_pad)
@@ -485,6 +492,7 @@ void ArrayUtils::accessIndex(ArrayType const& _arrayType) const
switch (location)
{
case DataLocation::CallData:
+ case DataLocation::Memory:
if (!_arrayType.isByteArray())
{
m_context << eth::Instruction::SWAP1;
@@ -494,7 +502,7 @@ void ArrayUtils::accessIndex(ArrayType const& _arrayType) const
if (_arrayType.getBaseType()->isValueType())
CompilerUtils(m_context).loadFromMemoryDynamic(
*_arrayType.getBaseType(),
- true,
+ location == DataLocation::CallData,
!_arrayType.isByteArray(),
false
);
@@ -527,8 +535,6 @@ void ArrayUtils::accessIndex(ArrayType const& _arrayType) const
m_context << eth::Instruction::ADD << u256(0);
}
break;
- case DataLocation::Memory:
- solAssert(false, "Memory lvalues not yet implemented.");
}
}
diff --git a/ExpressionCompiler.cpp b/ExpressionCompiler.cpp
index bfb945d8..4714b84e 100644
--- a/ExpressionCompiler.cpp
+++ b/ExpressionCompiler.cpp
@@ -724,8 +724,8 @@ void ExpressionCompiler::endVisit(MemberAccess const& _memberAccess)
case DataLocation::Storage:
setLValue<StorageArrayLength>(_memberAccess, type);
break;
- default:
- solAssert(false, "Unsupported array location.");
+ case DataLocation::Memory:
+ m_context << eth::Instruction::MLOAD;
break;
}
break;