mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Merge pull request #5316 from lazaridiscom/4891-memory-store-asserts
refine memory-store assertions, closes #4891
This commit is contained in:
commit
4d82831b06
@ -142,9 +142,13 @@ void CompilerUtils::storeInMemory(unsigned _offset)
|
|||||||
|
|
||||||
void CompilerUtils::storeInMemoryDynamic(Type const& _type, bool _padToWordBoundaries)
|
void CompilerUtils::storeInMemoryDynamic(Type const& _type, bool _padToWordBoundaries)
|
||||||
{
|
{
|
||||||
|
// process special types (Reference, StringLiteral, Function)
|
||||||
if (auto ref = dynamic_cast<ReferenceType const*>(&_type))
|
if (auto ref = dynamic_cast<ReferenceType const*>(&_type))
|
||||||
{
|
{
|
||||||
solUnimplementedAssert(ref->location() == DataLocation::Memory, "Only in-memory reference type can be stored.");
|
solUnimplementedAssert(
|
||||||
|
ref->location() == DataLocation::Memory,
|
||||||
|
"Only in-memory reference type can be stored."
|
||||||
|
);
|
||||||
storeInMemoryDynamic(IntegerType(256), _padToWordBoundaries);
|
storeInMemoryDynamic(IntegerType(256), _padToWordBoundaries);
|
||||||
}
|
}
|
||||||
else if (auto str = dynamic_cast<StringLiteralType const*>(&_type))
|
else if (auto str = dynamic_cast<StringLiteralType const*>(&_type))
|
||||||
@ -166,18 +170,18 @@ void CompilerUtils::storeInMemoryDynamic(Type const& _type, bool _padToWordBound
|
|||||||
m_context << Instruction::DUP2 << Instruction::MSTORE;
|
m_context << Instruction::DUP2 << Instruction::MSTORE;
|
||||||
m_context << u256(_padToWordBoundaries ? 32 : 24) << Instruction::ADD;
|
m_context << u256(_padToWordBoundaries ? 32 : 24) << Instruction::ADD;
|
||||||
}
|
}
|
||||||
else
|
else if (_type.isValueType())
|
||||||
{
|
{
|
||||||
unsigned numBytes = prepareMemoryStore(_type, _padToWordBoundaries);
|
unsigned numBytes = prepareMemoryStore(_type, _padToWordBoundaries);
|
||||||
if (numBytes > 0)
|
m_context << Instruction::DUP2 << Instruction::MSTORE;
|
||||||
{
|
m_context << u256(numBytes) << Instruction::ADD;
|
||||||
solUnimplementedAssert(
|
}
|
||||||
_type.sizeOnStack() == 1,
|
else // Should never happen
|
||||||
"Memory store of types with stack size != 1 not implemented."
|
{
|
||||||
);
|
solAssert(
|
||||||
m_context << Instruction::DUP2 << Instruction::MSTORE;
|
false,
|
||||||
m_context << u256(numBytes) << Instruction::ADD;
|
"Memory store of type " + _type.toString(true) + " not allowed."
|
||||||
}
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1266,18 +1270,30 @@ void CompilerUtils::rightShiftNumberOnStack(unsigned _bits)
|
|||||||
|
|
||||||
unsigned CompilerUtils::prepareMemoryStore(Type const& _type, bool _padToWords)
|
unsigned CompilerUtils::prepareMemoryStore(Type const& _type, bool _padToWords)
|
||||||
{
|
{
|
||||||
|
solAssert(
|
||||||
|
_type.sizeOnStack() == 1,
|
||||||
|
"Memory store of types with stack size != 1 not allowed (Type: " + _type.toString(true) + ")."
|
||||||
|
);
|
||||||
|
|
||||||
unsigned numBytes = _type.calldataEncodedSize(_padToWords);
|
unsigned numBytes = _type.calldataEncodedSize(_padToWords);
|
||||||
|
|
||||||
|
solAssert(
|
||||||
|
numBytes > 0,
|
||||||
|
"Memory store of 0 bytes requested (Type: " + _type.toString(true) + ")."
|
||||||
|
);
|
||||||
|
|
||||||
|
solAssert(
|
||||||
|
numBytes <= 32,
|
||||||
|
"Memory store of more than 32 bytes requested (Type: " + _type.toString(true) + ")."
|
||||||
|
);
|
||||||
|
|
||||||
bool leftAligned = _type.category() == Type::Category::FixedBytes;
|
bool leftAligned = _type.category() == Type::Category::FixedBytes;
|
||||||
if (numBytes == 0)
|
|
||||||
m_context << Instruction::POP;
|
convertType(_type, _type, true);
|
||||||
else
|
if (numBytes != 32 && !leftAligned && !_padToWords)
|
||||||
{
|
// shift the value accordingly before storing
|
||||||
solAssert(numBytes <= 32, "Memory store of more than 32 bytes requested.");
|
leftShiftNumberOnStack((32 - numBytes) * 8);
|
||||||
convertType(_type, _type, true);
|
|
||||||
if (numBytes != 32 && !leftAligned && !_padToWords)
|
|
||||||
// shift the value accordingly before storing
|
|
||||||
leftShiftNumberOnStack((32 - numBytes) * 8);
|
|
||||||
}
|
|
||||||
return numBytes;
|
return numBytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user