aboutsummaryrefslogtreecommitdiffstats
path: root/ExpressionCompiler.cpp
diff options
context:
space:
mode:
authorliana <liana@ethdev.com>2015-01-24 00:36:12 +0800
committerliana <liana@ethdev.com>2015-01-24 00:45:37 +0800
commit5de93e6acb81b9a39c1e8f1772dde81d5131e7e3 (patch)
treeaec395a0f6011b1216c0ccc2f2a91e2e5d4bbc33 /ExpressionCompiler.cpp
parent376c6182ad813384af43bdf198c4afd596699750 (diff)
downloaddexon-solidity-5de93e6acb81b9a39c1e8f1772dde81d5131e7e3.tar.gz
dexon-solidity-5de93e6acb81b9a39c1e8f1772dde81d5131e7e3.tar.zst
dexon-solidity-5de93e6acb81b9a39c1e8f1772dde81d5131e7e3.zip
- added conversion for string/hash of equal sizes
- added tests
Diffstat (limited to 'ExpressionCompiler.cpp')
-rw-r--r--ExpressionCompiler.cpp30
1 files changed, 28 insertions, 2 deletions
diff --git a/ExpressionCompiler.cpp b/ExpressionCompiler.cpp
index 60c5c4de..66ca2ec1 100644
--- a/ExpressionCompiler.cpp
+++ b/ExpressionCompiler.cpp
@@ -628,7 +628,33 @@ void ExpressionCompiler::appendTypeConversion(Type const& _typeOnStack, Type con
return;
Type::Category stackTypeCategory = _typeOnStack.getCategory();
Type::Category targetTypeCategory = _targetType.getCategory();
- if (stackTypeCategory == Type::Category::INTEGER || stackTypeCategory == Type::Category::CONTRACT ||
+
+ if (stackTypeCategory == Type::Category::STRING && targetTypeCategory == Type::Category::INTEGER)
+ {
+ // conversion from string to hash. no need to clean the high bit
+ // only to shift right because of opposite alignment
+ IntegerType const& targetIntegerType = dynamic_cast<IntegerType const&>(_targetType);
+ StaticStringType const& sourceStringType = dynamic_cast<StaticStringType const&>(_typeOnStack);
+ if (targetIntegerType.isHash())
+ {
+ solAssert(targetIntegerType.getNumBits() == sourceStringType.getNumBytes() * 8, "The size should be the same.");
+ m_context << u256(std::pow(2, 256 - sourceStringType.getNumBytes() * 8)) <<
+ eth::Instruction::SWAP1 << eth::Instruction::DIV;
+ }
+ }
+ else if (targetTypeCategory == Type::Category::STRING && stackTypeCategory == Type::Category::INTEGER)
+ {
+ // conversion from hash to string. no need to clean the high bit
+ // only to shift left because of opposite alignment
+ StaticStringType const& targetStringType = dynamic_cast<StaticStringType const&>(_targetType);
+ IntegerType const& sourceIntegerType = dynamic_cast<IntegerType const&>(_typeOnStack);
+ if (sourceIntegerType.isHash())
+ {
+ solAssert(sourceIntegerType.getNumBits() == targetStringType.getNumBytes() * 8, "The size should be the same.");
+ m_context << u256(std::pow(2, 256 - sourceIntegerType.getNumBits())) << eth::Instruction::MUL;
+ }
+ }
+ else if (stackTypeCategory == Type::Category::INTEGER || stackTypeCategory == Type::Category::CONTRACT ||
stackTypeCategory == Type::Category::INTEGER_CONSTANT)
{
solAssert(targetTypeCategory == Type::Category::INTEGER || targetTypeCategory == Type::Category::CONTRACT, "");
@@ -657,7 +683,7 @@ void ExpressionCompiler::appendTypeConversion(Type const& _typeOnStack, Type con
}
else if (stackTypeCategory == Type::Category::STRING)
{
- solAssert(targetTypeCategory == Type::Category::STRING, "");
+ solAssert(targetTypeCategory == Type::Category::STRING || targetTypeCategory == Type::Category::INTEGER, "Invalid type conversion requested.");
// nothing to do, strings are high-order-bit-aligned
//@todo clear lower-order bytes if we allow explicit conversion to shorter strings
}