aboutsummaryrefslogtreecommitdiffstats
path: root/libsolidity/codegen
diff options
context:
space:
mode:
authorLazaridis <info@lazaridis.com>2018-10-11 13:25:27 +0800
committerLazaridis <info@lazaridis.com>2018-10-27 05:04:54 +0800
commitcab8dea7fe676ded3d7d682db0a2233012333e5f (patch)
tree6a9708665e998260f1683d50ef79cdac38762112 /libsolidity/codegen
parent6859ec043412ddb1da1929fec4064fbd288db71e (diff)
downloaddexon-solidity-cab8dea7fe676ded3d7d682db0a2233012333e5f.tar
dexon-solidity-cab8dea7fe676ded3d7d682db0a2233012333e5f.tar.gz
dexon-solidity-cab8dea7fe676ded3d7d682db0a2233012333e5f.tar.bz2
dexon-solidity-cab8dea7fe676ded3d7d682db0a2233012333e5f.tar.lz
dexon-solidity-cab8dea7fe676ded3d7d682db0a2233012333e5f.tar.xz
dexon-solidity-cab8dea7fe676ded3d7d682db0a2233012333e5f.tar.zst
dexon-solidity-cab8dea7fe676ded3d7d682db0a2233012333e5f.zip
refine memory-store assertions, closes #4891
Diffstat (limited to 'libsolidity/codegen')
-rw-r--r--libsolidity/codegen/CompilerUtils.cpp58
1 files changed, 37 insertions, 21 deletions
diff --git a/libsolidity/codegen/CompilerUtils.cpp b/libsolidity/codegen/CompilerUtils.cpp
index 2bdf88e3..d89d023e 100644
--- a/libsolidity/codegen/CompilerUtils.cpp
+++ b/libsolidity/codegen/CompilerUtils.cpp
@@ -142,9 +142,13 @@ void CompilerUtils::storeInMemory(unsigned _offset)
void CompilerUtils::storeInMemoryDynamic(Type const& _type, bool _padToWordBoundaries)
{
+ // process special types (Reference, StringLiteral, Function)
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);
}
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 << u256(_padToWordBoundaries ? 32 : 24) << Instruction::ADD;
}
- else
+ else if (_type.isValueType())
{
unsigned numBytes = prepareMemoryStore(_type, _padToWordBoundaries);
- if (numBytes > 0)
- {
- solUnimplementedAssert(
- _type.sizeOnStack() == 1,
- "Memory store of types with stack size != 1 not implemented."
- );
- m_context << Instruction::DUP2 << Instruction::MSTORE;
- m_context << u256(numBytes) << Instruction::ADD;
- }
+ m_context << Instruction::DUP2 << Instruction::MSTORE;
+ m_context << u256(numBytes) << Instruction::ADD;
+ }
+ else // Should never happen
+ {
+ solAssert(
+ false,
+ "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)
{
+ solAssert(
+ _type.sizeOnStack() == 1,
+ "Memory store of types with stack size != 1 not allowed (Type: " + _type.toString(true) + ")."
+ );
+
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;
- if (numBytes == 0)
- m_context << Instruction::POP;
- else
- {
- solAssert(numBytes <= 32, "Memory store of more than 32 bytes requested.");
- convertType(_type, _type, true);
- if (numBytes != 32 && !leftAligned && !_padToWords)
- // shift the value accordingly before storing
- 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;
}