diff options
Diffstat (limited to 'libsolidity/codegen/LValue.cpp')
-rw-r--r-- | libsolidity/codegen/LValue.cpp | 19 |
1 files changed, 13 insertions, 6 deletions
diff --git a/libsolidity/codegen/LValue.cpp b/libsolidity/codegen/LValue.cpp index 3f1730d1..23fe2d4e 100644 --- a/libsolidity/codegen/LValue.cpp +++ b/libsolidity/codegen/LValue.cpp @@ -216,11 +216,14 @@ void StorageItem::retrieveValue(SourceLocation const&, bool _remove) const void StorageItem::storeValue(Type const& _sourceType, SourceLocation const& _location, bool _move) const { CompilerUtils utils(m_context); + solAssert(m_dataType, ""); + // stack: value storage_key storage_offset if (m_dataType->isValueType()) { solAssert(m_dataType->storageBytes() <= 32, "Invalid storage bytes size."); solAssert(m_dataType->storageBytes() > 0, "Invalid storage bytes size."); + if (m_dataType->storageBytes() == 32) { solAssert(m_dataType->sizeOnStack() == 1, "Invalid stack size."); @@ -228,6 +231,11 @@ void StorageItem::storeValue(Type const& _sourceType, SourceLocation const& _loc m_context << Instruction::POP; if (!_move) m_context << Instruction::DUP2 << Instruction::SWAP1; + + m_context << Instruction::SWAP1; + utils.convertType(_sourceType, *m_dataType, true); + m_context << Instruction::SWAP1; + m_context << Instruction::SSTORE; } else @@ -248,6 +256,7 @@ void StorageItem::storeValue(Type const& _sourceType, SourceLocation const& _loc // stack: value storage_ref cleared_value multiplier value if (FunctionType const* fun = dynamic_cast<decltype(fun)>(m_dataType)) { + solAssert(_sourceType == *m_dataType, "function item stored but target is not equal to source"); if (fun->location() == FunctionType::Location::External) // Combine the two-item function type into a single stack slot. utils.combineExternalFunctionType(false); @@ -257,19 +266,17 @@ void StorageItem::storeValue(Type const& _sourceType, SourceLocation const& _loc Instruction::AND; } else if (m_dataType->category() == Type::Category::FixedBytes) + { + solAssert(_sourceType.category() == Type::Category::FixedBytes, "source not fixed bytes"); m_context << (u256(0x1) << (256 - 8 * dynamic_cast<FixedBytesType const&>(*m_dataType).numBytes())) << Instruction::SWAP1 << Instruction::DIV; + } else { solAssert(m_dataType->sizeOnStack() == 1, "Invalid stack size for opaque type."); // remove the higher order bits - m_context - << (u256(1) << (8 * (32 - m_dataType->storageBytes()))) - << Instruction::SWAP1 - << Instruction::DUP2 - << Instruction::MUL - << Instruction::DIV; + utils.convertType(_sourceType, *m_dataType, true, true); } m_context << Instruction::MUL << Instruction::OR; // stack: value storage_ref updated_value |