aboutsummaryrefslogtreecommitdiffstats
path: root/libsolidity/codegen/CompilerUtils.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'libsolidity/codegen/CompilerUtils.cpp')
-rw-r--r--libsolidity/codegen/CompilerUtils.cpp43
1 files changed, 32 insertions, 11 deletions
diff --git a/libsolidity/codegen/CompilerUtils.cpp b/libsolidity/codegen/CompilerUtils.cpp
index 36ed480e..efb9b10a 100644
--- a/libsolidity/codegen/CompilerUtils.cpp
+++ b/libsolidity/codegen/CompilerUtils.cpp
@@ -323,18 +323,17 @@ void CompilerUtils::convertType(Type const& _typeOnStack, Type const& _targetTyp
}
else
{
- // clear lower-order bytes for conversion to shorter bytes - we always clean
+ // clear for conversion to longer bytes
solAssert(targetTypeCategory == Type::Category::FixedBytes, "Invalid type conversion requested.");
FixedBytesType const& targetType = dynamic_cast<FixedBytesType const&>(_targetType);
- if (targetType.numBytes() < typeOnStack.numBytes())
+ if (targetType.numBytes() > typeOnStack.numBytes() || _cleanupNeeded)
{
- if (targetType.numBytes() == 0)
- m_context << Instruction::DUP1 << Instruction::XOR;
+ if (typeOnStack.numBytes() == 0)
+ m_context << Instruction::POP << u256(0);
else
{
- m_context << (u256(1) << (256 - targetType.numBytes() * 8));
- m_context << Instruction::DUP1 << Instruction::SWAP2;
- m_context << Instruction::DIV << Instruction::MUL;
+ m_context << ((u256(1) << (256 - typeOnStack.numBytes() * 8)) - 1);
+ m_context << Instruction::NOT << Instruction::AND;
}
}
}
@@ -343,12 +342,14 @@ void CompilerUtils::convertType(Type const& _typeOnStack, Type const& _targetTyp
case Type::Category::Enum:
solAssert(targetTypeCategory == Type::Category::Integer || targetTypeCategory == Type::Category::Enum, "");
break;
+ case Type::Category::FixedPoint:
+ solAssert(false, "Not yet implemented - FixedPointType.");
case Type::Category::Integer:
case Type::Category::Contract:
- case Type::Category::IntegerConstant:
+ case Type::Category::RationalNumber:
if (targetTypeCategory == Type::Category::FixedBytes)
{
- solAssert(stackTypeCategory == Type::Category::Integer || stackTypeCategory == Type::Category::IntegerConstant,
+ solAssert(stackTypeCategory == Type::Category::Integer || stackTypeCategory == Type::Category::RationalNumber,
"Invalid conversion to FixedBytesType requested.");
// conversion from bytes to string. no need to clean the high bit
// only to shift left because of opposite alignment
@@ -361,17 +362,33 @@ void CompilerUtils::convertType(Type const& _typeOnStack, Type const& _targetTyp
else if (targetTypeCategory == Type::Category::Enum)
// just clean
convertType(_typeOnStack, *_typeOnStack.mobileType(), true);
+ else if (targetTypeCategory == Type::Category::FixedPoint)
+ {
+ solAssert(
+ stackTypeCategory == Type::Category::Integer ||
+ stackTypeCategory == Type::Category::RationalNumber ||
+ stackTypeCategory == Type::Category::FixedPoint,
+ "Invalid conversion to FixedMxNType requested."
+ );
+ //shift all integer bits onto the left side of the fixed type
+ FixedPointType const& targetFixedPointType = dynamic_cast<FixedPointType const&>(_targetType);
+ if (auto typeOnStack = dynamic_cast<IntegerType const*>(&_typeOnStack))
+ if (targetFixedPointType.integerBits() > typeOnStack->numBits())
+ cleanHigherOrderBits(*typeOnStack);
+ solAssert(false, "Not yet implemented - FixedPointType.");
+ }
else
{
solAssert(targetTypeCategory == Type::Category::Integer || targetTypeCategory == Type::Category::Contract, "");
IntegerType addressType(0, IntegerType::Modifier::Address);
IntegerType const& targetType = targetTypeCategory == Type::Category::Integer
? dynamic_cast<IntegerType const&>(_targetType) : addressType;
- if (stackTypeCategory == Type::Category::IntegerConstant)
+ if (stackTypeCategory == Type::Category::RationalNumber)
{
- IntegerConstantType const& constType = dynamic_cast<IntegerConstantType const&>(_typeOnStack);
+ RationalNumberType const& constType = dynamic_cast<RationalNumberType const&>(_typeOnStack);
// We know that the stack is clean, we only have to clean for a narrowing conversion
// where cleanup is forced.
+ solAssert(!constType.isFractional(), "Not yet implemented - FixedPointType.");
if (targetType.numBits() < constType.integerType()->numBits() && _cleanupNeeded)
cleanHigherOrderBits(targetType);
}
@@ -619,6 +636,10 @@ void CompilerUtils::convertType(Type const& _typeOnStack, Type const& _targetTyp
}
break;
}
+ case Type::Category::Bool:
+ solAssert(_targetType == _typeOnStack, "Invalid conversion for bool.");
+ if (_cleanupNeeded)
+ m_context << Instruction::ISZERO << Instruction::ISZERO;
default:
// All other types should not be convertible to non-equal types.
solAssert(_typeOnStack == _targetType, "Invalid type conversion requested.");