diff options
author | chriseth <c@ethdev.com> | 2015-03-06 20:00:54 +0800 |
---|---|---|
committer | chriseth <c@ethdev.com> | 2015-03-06 20:17:52 +0800 |
commit | 11e943fc6a23c78279fcda01fb5acdc28c6fd6e3 (patch) | |
tree | 86445b5d10a62387c4231ce6f446a8e321763492 | |
parent | d8b156ecbbb4d470ba3432975694585dd5a019e2 (diff) | |
download | dexon-solidity-11e943fc6a23c78279fcda01fb5acdc28c6fd6e3.tar.gz dexon-solidity-11e943fc6a23c78279fcda01fb5acdc28c6fd6e3.tar.zst dexon-solidity-11e943fc6a23c78279fcda01fb5acdc28c6fd6e3.zip |
Fix for arrays containing mappings.
-rw-r--r-- | ArrayUtils.cpp | 19 | ||||
-rw-r--r-- | LValue.cpp | 1 |
2 files changed, 18 insertions, 2 deletions
diff --git a/ArrayUtils.cpp b/ArrayUtils.cpp index 3619b540..f0d7d6a8 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; @@ -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) |