diff options
author | Daniel Kirchner <daniel@ekpyron.org> | 2018-09-03 23:45:58 +0800 |
---|---|---|
committer | Daniel Kirchner <daniel@ekpyron.org> | 2018-09-05 18:19:14 +0800 |
commit | 87804b6419a5894601441efe511015adda5fb119 (patch) | |
tree | 72fc5334d21933570c8b94ec6a22879c98a692ca /libsolidity/codegen | |
parent | a996ea266c4542b37503c1d2261a17f3d5a55dbb (diff) | |
download | dexon-solidity-87804b6419a5894601441efe511015adda5fb119.tar.gz dexon-solidity-87804b6419a5894601441efe511015adda5fb119.tar.zst dexon-solidity-87804b6419a5894601441efe511015adda5fb119.zip |
Split IntegerType into IntegerType and AddressType.
Diffstat (limited to 'libsolidity/codegen')
-rw-r--r-- | libsolidity/codegen/ABIFunctions.cpp | 27 | ||||
-rw-r--r-- | libsolidity/codegen/CompilerUtils.cpp | 27 | ||||
-rw-r--r-- | libsolidity/codegen/ExpressionCompiler.cpp | 15 |
3 files changed, 52 insertions, 17 deletions
diff --git a/libsolidity/codegen/ABIFunctions.cpp b/libsolidity/codegen/ABIFunctions.cpp index dda77958..5e5fe84a 100644 --- a/libsolidity/codegen/ABIFunctions.cpp +++ b/libsolidity/codegen/ABIFunctions.cpp @@ -197,6 +197,9 @@ string ABIFunctions::cleanupFunction(Type const& _type, bool _revertOnFailure) templ("functionName", functionName); switch (_type.category()) { + case Type::Category::Address: + templ("body", "cleaned := " + cleanupFunction(IntegerType(160)) + "(value)"); + break; case Type::Category::Integer: { IntegerType const& type = dynamic_cast<IntegerType const&>(_type); @@ -239,7 +242,7 @@ string ABIFunctions::cleanupFunction(Type const& _type, bool _revertOnFailure) break; } case Type::Category::Contract: - templ("body", "cleaned := " + cleanupFunction(IntegerType(160, IntegerType::Modifier::Address)) + "(value)"); + templ("body", "cleaned := " + cleanupFunction(AddressType()) + "(value)"); break; case Type::Category::Enum: { @@ -284,6 +287,12 @@ string ABIFunctions::conversionFunction(Type const& _from, Type const& _to) auto fromCategory = _from.category(); switch (fromCategory) { + case Type::Category::Address: + body = + Whiskers("converted := <convert>(value)") + ("convert", conversionFunction(IntegerType(160), _to)) + .render(); + break; case Type::Category::Integer: case Type::Category::RationalNumber: case Type::Category::Contract: @@ -314,16 +323,19 @@ string ABIFunctions::conversionFunction(Type const& _from, Type const& _to) .render(); } else if (toCategory == Type::Category::FixedPoint) - { solUnimplemented("Not yet implemented - FixedPointType."); - } + else if (toCategory == Type::Category::Address) + body = + Whiskers("converted := <convert>(value)") + ("convert", conversionFunction(_from, IntegerType(160))) + .render(); else { solAssert( toCategory == Type::Category::Integer || toCategory == Type::Category::Contract, ""); - IntegerType const addressType(160, IntegerType::Modifier::Address); + IntegerType const addressType(160); IntegerType const& to = toCategory == Type::Category::Integer ? dynamic_cast<IntegerType const&>(_to) : @@ -375,6 +387,11 @@ string ABIFunctions::conversionFunction(Type const& _from, Type const& _to) ("shift", shiftRightFunction(256 - from.numBytes() * 8)) ("convert", conversionFunction(IntegerType(from.numBytes() * 8), _to)) .render(); + else if (toCategory == Type::Category::Address) + body = + Whiskers("converted := <convert>(value)") + ("convert", conversionFunction(_from, IntegerType(160))) + .render(); else { // clear for conversion to longer bytes @@ -410,7 +427,7 @@ string ABIFunctions::conversionFunction(Type const& _from, Type const& _to) solAssert(false, ""); } - solAssert(!body.empty(), ""); + solAssert(!body.empty(), _from.canonicalName() + " to " + _to.canonicalName()); templ("body", body); return templ.render(); }); diff --git a/libsolidity/codegen/CompilerUtils.cpp b/libsolidity/codegen/CompilerUtils.cpp index b30851fb..e6ad6d9c 100644 --- a/libsolidity/codegen/CompilerUtils.cpp +++ b/libsolidity/codegen/CompilerUtils.cpp @@ -657,6 +657,11 @@ void CompilerUtils::convertType( if (targetIntegerType.numBits() < typeOnStack.numBytes() * 8) convertType(IntegerType(typeOnStack.numBytes() * 8), _targetType, _cleanupNeeded); } + else if (targetTypeCategory == Type::Category::Address) + { + solAssert(typeOnStack.numBytes() * 8 == 160, ""); + rightShiftNumberOnStack(256 - 160); + } else { // clear for conversion to longer bytes @@ -690,23 +695,33 @@ void CompilerUtils::convertType( break; case Type::Category::FixedPoint: solUnimplemented("Not yet implemented - FixedPointType."); + case Type::Category::Address: case Type::Category::Integer: case Type::Category::Contract: case Type::Category::RationalNumber: if (targetTypeCategory == Type::Category::FixedBytes) { - solAssert(stackTypeCategory == Type::Category::Integer || stackTypeCategory == Type::Category::RationalNumber, - "Invalid conversion to FixedBytesType requested."); + solAssert( + stackTypeCategory == Type::Category::Address || + 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 FixedBytesType const& targetBytesType = dynamic_cast<FixedBytesType const&>(_targetType); if (auto typeOnStack = dynamic_cast<IntegerType const*>(&_typeOnStack)) + { if (targetBytesType.numBytes() * 8 > typeOnStack->numBits()) cleanHigherOrderBits(*typeOnStack); + } + else if (stackTypeCategory == Type::Category::Address) + solAssert(targetBytesType.numBytes() * 8 == 160, ""); leftShiftNumberOnStack(256 - targetBytesType.numBytes() * 8); } else if (targetTypeCategory == Type::Category::Enum) { + solAssert(stackTypeCategory != Type::Category::Address, "Invalid conversion to EnumType requested."); solAssert(_typeOnStack.mobileType(), ""); // just clean convertType(_typeOnStack, *_typeOnStack.mobileType(), true); @@ -733,8 +748,8 @@ void CompilerUtils::convertType( } else { - solAssert(targetTypeCategory == Type::Category::Integer || targetTypeCategory == Type::Category::Contract, ""); - IntegerType addressType(160, IntegerType::Modifier::Address); + solAssert(targetTypeCategory == Type::Category::Integer || targetTypeCategory == Type::Category::Contract || targetTypeCategory == Type::Category::Address, ""); + IntegerType addressType(160); IntegerType const& targetType = targetTypeCategory == Type::Category::Integer ? dynamic_cast<IntegerType const&>(_targetType) : addressType; if (stackTypeCategory == Type::Category::RationalNumber) @@ -996,10 +1011,8 @@ void CompilerUtils::convertType( m_context << Instruction::ISZERO << Instruction::ISZERO; break; default: - if (stackTypeCategory == Type::Category::Function && targetTypeCategory == Type::Category::Integer) + if (stackTypeCategory == Type::Category::Function && targetTypeCategory == Type::Category::Address) { - IntegerType const& targetType = dynamic_cast<IntegerType const&>(_targetType); - solAssert(targetType.isAddress(), "Function type can only be converted to address."); FunctionType const& typeOnStack = dynamic_cast<FunctionType const&>(_typeOnStack); solAssert(typeOnStack.kind() == FunctionType::Kind::External, "Only external function type can be converted."); diff --git a/libsolidity/codegen/ExpressionCompiler.cpp b/libsolidity/codegen/ExpressionCompiler.cpp index 4cc4ba53..4150bc11 100644 --- a/libsolidity/codegen/ExpressionCompiler.cpp +++ b/libsolidity/codegen/ExpressionCompiler.cpp @@ -1259,7 +1259,7 @@ bool ExpressionCompiler::visit(MemberAccess const& _memberAccess) identifier = FunctionType(*function).externalIdentifier(); else solAssert(false, "Contract member is neither variable nor function."); - utils().convertType(type, IntegerType(160, IntegerType::Modifier::Address), true); + utils().convertType(type, AddressType(), true); m_context << identifier; } else @@ -1268,11 +1268,16 @@ bool ExpressionCompiler::visit(MemberAccess const& _memberAccess) } case Type::Category::Integer: { + solAssert(false, "Invalid member access to integer"); + break; + } + case Type::Category::Address: + { if (member == "balance") { utils().convertType( *_memberAccess.expression().annotation().type, - IntegerType(160, IntegerType::Modifier::Address), + AddressType(), true ); m_context << Instruction::BALANCE; @@ -1280,11 +1285,11 @@ bool ExpressionCompiler::visit(MemberAccess const& _memberAccess) else if ((set<string>{"send", "transfer", "call", "callcode", "delegatecall", "staticcall"}).count(member)) utils().convertType( *_memberAccess.expression().annotation().type, - IntegerType(160, IntegerType::Modifier::Address), + AddressType(), true ); else - solAssert(false, "Invalid member access to integer"); + solAssert(false, "Invalid member access to address"); break; } case Type::Category::Function: @@ -1578,7 +1583,7 @@ void ExpressionCompiler::endVisit(Literal const& _literal) { case Type::Category::RationalNumber: case Type::Category::Bool: - case Type::Category::Integer: + case Type::Category::Address: m_context << type->literalValue(&_literal); break; case Type::Category::StringLiteral: |