aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLefteris Karapetsas <lefteris@refu.co>2015-03-11 01:22:19 +0800
committerLefteris Karapetsas <lefteris@refu.co>2015-03-12 19:53:00 +0800
commitb2fadf6b933e9034d5edb49608329fb0f7d015dd (patch)
treea0f606a88174cbdb99dcab2d3ee9a23fe47ae8d6
parent73ce24ae75554b18a342e1e510f37f99057fdb1d (diff)
downloaddexon-solidity-b2fadf6b933e9034d5edb49608329fb0f7d015dd.tar
dexon-solidity-b2fadf6b933e9034d5edb49608329fb0f7d015dd.tar.gz
dexon-solidity-b2fadf6b933e9034d5edb49608329fb0f7d015dd.tar.bz2
dexon-solidity-b2fadf6b933e9034d5edb49608329fb0f7d015dd.tar.lz
dexon-solidity-b2fadf6b933e9034d5edb49608329fb0f7d015dd.tar.xz
dexon-solidity-b2fadf6b933e9034d5edb49608329fb0f7d015dd.tar.zst
dexon-solidity-b2fadf6b933e9034d5edb49608329fb0f7d015dd.zip
Conversion changes after renaming Hash/String to Bytes.
- Almost all end to end tests pass. Still needs a little bit of work
-rw-r--r--ExpressionCompiler.cpp49
-rw-r--r--GlobalContext.cpp2
-rw-r--r--LValue.cpp8
-rw-r--r--Types.cpp20
4 files changed, 47 insertions, 32 deletions
diff --git a/ExpressionCompiler.cpp b/ExpressionCompiler.cpp
index 089ebc32..f00b2d40 100644
--- a/ExpressionCompiler.cpp
+++ b/ExpressionCompiler.cpp
@@ -123,16 +123,20 @@ void ExpressionCompiler::appendTypeConversion(Type const& _typeOnStack, Type con
Type::Category stackTypeCategory = _typeOnStack.getCategory();
Type::Category targetTypeCategory = _targetType.getCategory();
- if (stackTypeCategory == Type::Category::FixedBytes)
+ switch (stackTypeCategory)
+ {
+ case Type::Category::FixedBytes:
{
FixedBytesType const& typeOnStack = dynamic_cast<FixedBytesType const&>(_typeOnStack);
if (targetTypeCategory == Type::Category::Integer)
{
- // conversion from string to bytes. no need to clean the high bit
+ // conversion from bytes to integer. no need to clean the high bit
// only to shift right because of opposite alignment
IntegerType const& targetIntegerType = dynamic_cast<IntegerType const&>(_targetType);
- solAssert(targetIntegerType.getNumBits() == typeOnStack.getNumBytes() * 8, "The size should be the same.");
+ // solAssert(targetIntegerType.getNumBits() == typeOnStack.getNumBytes() * 8, "The size should be the same.");
m_context << (u256(1) << (256 - typeOnStack.getNumBytes() * 8)) << eth::Instruction::SWAP1 << eth::Instruction::DIV;
+ if (targetIntegerType.getNumBits() < typeOnStack.getNumBytes() * 8)
+ appendTypeConversion(IntegerType(typeOnStack.getNumBytes() * 8), _targetType, _cleanupNeeded);
}
else
{
@@ -150,21 +154,24 @@ void ExpressionCompiler::appendTypeConversion(Type const& _typeOnStack, Type con
}
}
}
- else if (stackTypeCategory == Type::Category::Enum)
- solAssert(targetTypeCategory == Type::Category::Integer ||
- targetTypeCategory == Type::Category::Enum, "");
- else if (stackTypeCategory == Type::Category::Integer ||
- stackTypeCategory == Type::Category::Contract ||
- stackTypeCategory == Type::Category::IntegerConstant)
- {
- if (targetTypeCategory == Type::Category::FixedBytes && stackTypeCategory == Type::Category::Integer)
+ break;
+ case Type::Category::Enum:
+ solAssert(targetTypeCategory == Type::Category::Integer || targetTypeCategory == Type::Category::Enum, "");
+ break;
+ case Type::Category::Integer:
+ case Type::Category::Contract:
+ case Type::Category::IntegerConstant:
+ if (targetTypeCategory == Type::Category::FixedBytes)
{
+ solAssert(stackTypeCategory == Type::Category::Integer || stackTypeCategory == Type::Category::IntegerConstant,
+ "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
FixedBytesType const& targetBytesType = dynamic_cast<FixedBytesType const&>(_targetType);
- IntegerType const& typeOnStack = dynamic_cast<IntegerType const&>(_typeOnStack);
- solAssert(typeOnStack.getNumBits() == targetBytesType.getNumBytes() * 8, "The size should be the same.");
- m_context << (u256(1) << (256 - typeOnStack.getNumBits())) << eth::Instruction::MUL;
+ if (auto typeOnStack = dynamic_cast<IntegerType const*>(&_typeOnStack))
+ if (targetBytesType.getNumBytes() * 8 > typeOnStack->getNumBits())
+ appendHighBitsCleanup(*typeOnStack);
+ m_context << (u256(1) << (256 - targetBytesType.getNumBytes() * 8)) << eth::Instruction::MUL;
}
else if (targetTypeCategory == Type::Category::Enum)
// just clean
@@ -174,7 +181,7 @@ void ExpressionCompiler::appendTypeConversion(Type const& _typeOnStack, Type con
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;
+ ? dynamic_cast<IntegerType const&>(_targetType) : addressType;
if (stackTypeCategory == Type::Category::IntegerConstant)
{
IntegerConstantType const& constType = dynamic_cast<IntegerConstantType const&>(_typeOnStack);
@@ -186,7 +193,7 @@ void ExpressionCompiler::appendTypeConversion(Type const& _typeOnStack, Type con
else
{
IntegerType const& typeOnStack = stackTypeCategory == Type::Category::Integer
- ? dynamic_cast<IntegerType const&>(_typeOnStack) : addressType;
+ ? dynamic_cast<IntegerType const&>(_typeOnStack) : addressType;
// Widening: clean up according to source type width
// Non-widening and force: clean up according to target type bits
if (targetType.getNumBits() > typeOnStack.getNumBits())
@@ -195,10 +202,12 @@ void ExpressionCompiler::appendTypeConversion(Type const& _typeOnStack, Type con
appendHighBitsCleanup(targetType);
}
}
- }
- else if (_typeOnStack != _targetType)
+ break;
+ default:
// All other types should not be convertible to non-equal types.
- BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Invalid type conversion requested."));
+ solAssert(_typeOnStack == _targetType, "Invalid type conversion requested.");
+ break;
+ }
}
bool ExpressionCompiler::visit(Assignment const& _assignment)
@@ -773,7 +782,7 @@ bool ExpressionCompiler::visit(IndexAccess const& _indexAccess)
// no lvalue, just retrieve the value
m_context
<< eth::Instruction::ADD << eth::Instruction::CALLDATALOAD
- << u256(0) << eth::Instruction::BYTE;
+ << ((u256(1) << (256 - 8)) - 1) << eth::Instruction::AND;
break;
case ArrayType::Location::Memory:
solAssert(false, "Memory lvalues not yet implemented.");
diff --git a/GlobalContext.cpp b/GlobalContext.cpp
index 7bd9c8df..80cebd76 100644
--- a/GlobalContext.cpp
+++ b/GlobalContext.cpp
@@ -55,7 +55,7 @@ m_magicVariables(vector<shared_ptr<MagicVariableDeclaration const>>{make_shared<
make_shared<MagicVariableDeclaration>("sha256",
make_shared<FunctionType>(strings(), strings{"bytes32"}, FunctionType::Location::SHA256, true)),
make_shared<MagicVariableDeclaration>("ecrecover",
- make_shared<FunctionType>(strings{"bytes32", "bytes1", "bytes32", "bytes32"}, strings{"address"}, FunctionType::Location::ECRecover)),
+ make_shared<FunctionType>(strings{"bytes32", "uint8", "bytes32", "bytes32"}, strings{"address"}, FunctionType::Location::ECRecover)),
make_shared<MagicVariableDeclaration>("ripemd160",
make_shared<FunctionType>(strings(), strings{"bytes20"}, FunctionType::Location::RIPEMD160, true))})
{
diff --git a/LValue.cpp b/LValue.cpp
index db3cd56b..7b8374b8 100644
--- a/LValue.cpp
+++ b/LValue.cpp
@@ -246,10 +246,11 @@ void StorageByteArrayElement::retrieveValue(SourceLocation const&, bool _remove)
// stack: ref byte_number
if (_remove)
m_context << eth::Instruction::SWAP1 << eth::Instruction::SLOAD
- << eth::Instruction::SWAP1 << eth::Instruction::BYTE;
+ << eth::Instruction::SWAP1 << eth::Instruction::BYTE ;
else
m_context << eth::Instruction::DUP2 << eth::Instruction::SLOAD
<< eth::Instruction::DUP2 << eth::Instruction::BYTE;
+ m_context << (u256(1) << (256 - 8)) << eth::Instruction::MUL;
}
void StorageByteArrayElement::storeValue(Type const&, SourceLocation const&, bool _move) const
@@ -265,8 +266,9 @@ void StorageByteArrayElement::storeValue(Type const&, SourceLocation const&, boo
m_context << eth::Instruction::DUP2 << u256(0xff) << eth::Instruction::MUL
<< eth::Instruction::NOT << eth::Instruction::AND;
// stack: value ref (1<<(32-byte_number)) old_full_value_with_cleared_byte
- m_context << eth::Instruction::SWAP1 << eth::Instruction::DUP4 << eth::Instruction::MUL
- << eth::Instruction::OR;
+ m_context << eth::Instruction::SWAP1;
+ m_context << (u256(1) << (256 - 8)) << eth::Instruction::DUP5 << eth::Instruction::DIV
+ << eth::Instruction::MUL << eth::Instruction::OR;
// stack: value ref new_full_value
m_context << eth::Instruction::SWAP1 << eth::Instruction::SSTORE;
if (_move)
diff --git a/Types.cpp b/Types.cpp
index 6039895a..8524cb8b 100644
--- a/Types.cpp
+++ b/Types.cpp
@@ -175,14 +175,10 @@ bool IntegerType::isImplicitlyConvertibleTo(Type const& _convertTo) const
bool IntegerType::isExplicitlyConvertibleTo(Type const& _convertTo) const
{
- if (_convertTo.getCategory() == Category::FixedBytes)
- {
- FixedBytesType const& convertTo = dynamic_cast<FixedBytesType const&>(_convertTo);
- return (m_bits == convertTo.getNumBytes() * 8);
- }
return _convertTo.getCategory() == getCategory() ||
_convertTo.getCategory() == Category::Contract ||
- _convertTo.getCategory() == Category::Enum;
+ _convertTo.getCategory() == Category::Enum ||
+ _convertTo.getCategory() == Category::FixedBytes;
}
TypePointer IntegerType::unaryOperatorResult(Token::Value _operator) const
@@ -284,7 +280,15 @@ IntegerConstantType::IntegerConstantType(Literal const& _literal)
bool IntegerConstantType::isImplicitlyConvertibleTo(Type const& _convertTo) const
{
- TypePointer integerType = getIntegerType();
+ auto integerType = getIntegerType();
+ if (_convertTo.getCategory() == Category::FixedBytes)
+ {
+ FixedBytesType const& convertTo = dynamic_cast<FixedBytesType const&>(_convertTo);
+ if (convertTo.getNumBytes() * 8 >= integerType->getNumBits())
+ return true;
+ return false;
+ }
+
return integerType && integerType->isImplicitlyConvertibleTo(_convertTo);
}
@@ -461,7 +465,7 @@ bool FixedBytesType::isExplicitlyConvertibleTo(Type const& _convertTo) const
if (_convertTo.getCategory() == Category::Integer)
{
IntegerType const& convertTo = dynamic_cast<IntegerType const&>(_convertTo);
- if (m_bytes * 8 == convertTo.getNumBits())
+ if (m_bytes * 8 <= convertTo.getNumBits())
return true;
}