diff options
author | chriseth <c@ethdev.com> | 2015-06-22 18:50:09 +0800 |
---|---|---|
committer | chriseth <c@ethdev.com> | 2015-06-23 02:50:47 +0800 |
commit | 2eabaa4716997242856b0e33bbc34a4d7204c301 (patch) | |
tree | 963d6aa6d25bc5df68075c0858e7fc36691a9198 | |
parent | ee520f602263ba0fc70d51f3317d98a59e115ae3 (diff) | |
download | dexon-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.cpp | 26 | ||||
-rw-r--r-- | ExpressionCompiler.cpp | 4 |
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; |