From 11e943fc6a23c78279fcda01fb5acdc28c6fd6e3 Mon Sep 17 00:00:00 2001 From: chriseth Date: Fri, 6 Mar 2015 13:00:54 +0100 Subject: [PATCH] Fix for arrays containing mappings. --- ArrayUtils.cpp | 19 +++++++++++++++++-- LValue.cpp | 1 + 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/ArrayUtils.cpp b/ArrayUtils.cpp index 3619b5408..f0d7d6a81 100644 --- a/ArrayUtils.cpp +++ b/ArrayUtils.cpp @@ -65,6 +65,16 @@ void ArrayUtils::copyArrayToStorage(ArrayType const& _targetType, ArrayType cons if (_targetType.isDynamicallySized()) // store new target length m_context << eth::Instruction::DUP3 << eth::Instruction::DUP3 << eth::Instruction::SSTORE; + if (sourceBaseType->getCategory() == Type::Category::Mapping) + { + solAssert(targetBaseType->getCategory() == Type::Category::Mapping, ""); + solAssert(_sourceType.getLocation() == ArrayType::Location::Storage, ""); + // nothing to copy + m_context + << eth::Instruction::POP << eth::Instruction::POP + << eth::Instruction::POP << eth::Instruction::POP; + return; + } // compute hashes (data positions) m_context << eth::Instruction::SWAP1; if (_targetType.isDynamicallySized()) @@ -114,7 +124,7 @@ void ArrayUtils::copyArrayToStorage(ArrayType const& _targetType, ArrayType cons else if (sourceBaseType->isValueType()) CompilerUtils(m_context).loadFromMemoryDynamic(*sourceBaseType, true, true, false); else - solAssert(false, "Copying of unknown type requested."); + solAssert(false, "Copying of unknown type requested: " + sourceBaseType->toString()); m_context << eth::dupInstruction(2 + sourceBaseType->getSizeOnStack()); StorageItem(m_context, *targetBaseType).storeValue(*sourceBaseType, SourceLocation(), true); } @@ -148,7 +158,7 @@ void ArrayUtils::clearArray(ArrayType const& _type) const solAssert(_type.getLocation() == ArrayType::Location::Storage, ""); if (_type.isDynamicallySized()) clearDynamicArray(_type); - else if (_type.getLength() == 0) + else if (_type.getLength() == 0 || _type.getBaseType()->getCategory() == Type::Category::Mapping) m_context << eth::Instruction::POP; else if (_type.getLength() < 5) // unroll loop for small arrays @todo choose a good value { @@ -242,6 +252,11 @@ void ArrayUtils::resizeDynamicArray(const ArrayType& _type) const void ArrayUtils::clearStorageLoop(Type const& _type) const { + if (_type.getCategory() == Type::Category::Mapping) + { + m_context << eth::Instruction::POP; + return; + } // stack: end_pos pos eth::AssemblyItem loopStart = m_context.newTag(); m_context << loopStart; diff --git a/LValue.cpp b/LValue.cpp index 7a81ff927..a036be80b 100644 --- a/LValue.cpp +++ b/LValue.cpp @@ -212,6 +212,7 @@ void StorageItem::setToZero(SourceLocation const&, bool _removeReference) const } else { + solAssert(m_dataType.isValueType(), "Clearing of unsupported type requested: " + m_dataType.toString()); if (m_size == 0 && _removeReference) m_context << eth::Instruction::POP; else if (m_size == 1)