aboutsummaryrefslogtreecommitdiffstats
path: root/libsolidity/codegen/ABIFunctions.cpp
diff options
context:
space:
mode:
authorchriseth <chris@ethereum.org>2018-11-14 02:33:35 +0800
committerGitHub <noreply@github.com>2018-11-14 02:33:35 +0800
commit1d4f565a64988a3400847d2655ca24f73f234bc6 (patch)
treecaaa6c26e307513505349b50ca4f2a8a9506752b /libsolidity/codegen/ABIFunctions.cpp
parent59dbf8f1085b8b92e8b7eb0ce380cbeb642e97eb (diff)
parent91b6b8a88e76016e0324036cb7a7f9300a1e2439 (diff)
downloaddexon-solidity-1d4f565a64988a3400847d2655ca24f73f234bc6.tar
dexon-solidity-1d4f565a64988a3400847d2655ca24f73f234bc6.tar.gz
dexon-solidity-1d4f565a64988a3400847d2655ca24f73f234bc6.tar.bz2
dexon-solidity-1d4f565a64988a3400847d2655ca24f73f234bc6.tar.lz
dexon-solidity-1d4f565a64988a3400847d2655ca24f73f234bc6.tar.xz
dexon-solidity-1d4f565a64988a3400847d2655ca24f73f234bc6.tar.zst
dexon-solidity-1d4f565a64988a3400847d2655ca24f73f234bc6.zip
Merge pull request #5416 from ethereum/develop
Merge develop into release for 0.5.0
Diffstat (limited to 'libsolidity/codegen/ABIFunctions.cpp')
-rw-r--r--libsolidity/codegen/ABIFunctions.cpp76
1 files changed, 49 insertions, 27 deletions
diff --git a/libsolidity/codegen/ABIFunctions.cpp b/libsolidity/codegen/ABIFunctions.cpp
index 3e3aa0ae..bd29b382 100644
--- a/libsolidity/codegen/ABIFunctions.cpp
+++ b/libsolidity/codegen/ABIFunctions.cpp
@@ -17,7 +17,7 @@
/**
* @author Christian <chris@ethereum.org>
* @date 2017
- * Routines that generate JULIA code related to ABI encoding, decoding and type conversions.
+ * Routines that generate Yul code related to ABI encoding, decoding and type conversions.
*/
#include <libsolidity/codegen/ABIFunctions.h>
@@ -49,7 +49,7 @@ string ABIFunctions::tupleEncoder(
if (_encodeAsLibraryTypes)
functionName += "_library";
- return createFunction(functionName, [&]() {
+ return createExternallyUsedFunction(functionName, [&]() {
solAssert(!_givenTypes.empty(), "");
// Note that the values are in reverse due to the difference in calling semantics.
@@ -113,7 +113,7 @@ string ABIFunctions::tupleDecoder(TypePointers const& _types, bool _fromMemory)
solAssert(!_types.empty(), "");
- return createFunction(functionName, [&]() {
+ return createExternallyUsedFunction(functionName, [&]() {
TypePointers decodingTypes;
for (auto const& t: _types)
decodingTypes.emplace_back(t->decodingType());
@@ -176,13 +176,13 @@ string ABIFunctions::tupleDecoder(TypePointers const& _types, bool _fromMemory)
});
}
-string ABIFunctions::requestedFunctions()
+pair<string, set<string>> ABIFunctions::requestedFunctions()
{
string result;
for (auto const& f: m_requestedFunctions)
result += f.second;
m_requestedFunctions.clear();
- return result;
+ return make_pair(result, std::move(m_externallyUsedFunctions));
}
string ABIFunctions::cleanupFunction(Type const& _type, bool _revertOnFailure)
@@ -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);
@@ -228,7 +231,8 @@ string ABIFunctions::cleanupFunction(Type const& _type, bool _revertOnFailure)
if (type.numBytes() == 32)
templ("body", "cleaned := value");
else if (type.numBytes() == 0)
- templ("body", "cleaned := 0");
+ // This is disallowed in the type system.
+ solAssert(false, "");
else
{
size_t numBits = type.numBytes() * 8;
@@ -238,8 +242,14 @@ string ABIFunctions::cleanupFunction(Type const& _type, bool _revertOnFailure)
break;
}
case Type::Category::Contract:
- templ("body", "cleaned := " + cleanupFunction(IntegerType(160, IntegerType::Modifier::Address)) + "(value)");
+ {
+ AddressType addressType(dynamic_cast<ContractType const&>(_type).isPayable() ?
+ StateMutability::Payable :
+ StateMutability::NonPayable
+ );
+ templ("body", "cleaned := " + cleanupFunction(addressType) + "(value)");
break;
+ }
case Type::Category::Enum:
{
size_t members = dynamic_cast<EnumType const&>(_type).numberOfMembers();
@@ -283,6 +293,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:
@@ -313,16 +329,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) :
@@ -374,6 +393,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
@@ -409,7 +433,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();
});
@@ -471,13 +495,8 @@ string ABIFunctions::abiEncodingFunction(
bool _fromStack
)
{
- solUnimplementedAssert(
- _to.mobileType() &&
- _to.mobileType()->interfaceType(_encodeAsLibraryTypes) &&
- _to.mobileType()->interfaceType(_encodeAsLibraryTypes)->encodingType(),
- "Encoding type \"" + _to.toString() + "\" not yet implemented."
- );
- TypePointer toInterface = _to.mobileType()->interfaceType(_encodeAsLibraryTypes)->encodingType();
+ TypePointer toInterface = _to.fullEncodingType(_encodeAsLibraryTypes, true, false);
+ solUnimplementedAssert(toInterface, "Encoding type \"" + _to.toString() + "\" not yet implemented.");
Type const& to = *toInterface;
if (_from.category() == Type::Category::StringLiteral)
@@ -886,13 +905,8 @@ string ABIFunctions::abiEncodingFunctionStruct(
solAssert(member.type, "");
if (!member.type->canLiveOutsideStorage())
continue;
- solUnimplementedAssert(
- member.type->mobileType() &&
- member.type->mobileType()->interfaceType(_encodeAsLibraryTypes) &&
- member.type->mobileType()->interfaceType(_encodeAsLibraryTypes)->encodingType(),
- "Encoding type \"" + member.type->toString() + "\" not yet implemented."
- );
- auto memberTypeTo = member.type->mobileType()->interfaceType(_encodeAsLibraryTypes)->encodingType();
+ TypePointer memberTypeTo = member.type->fullEncodingType(_encodeAsLibraryTypes, true, false);
+ solUnimplementedAssert(memberTypeTo, "Encoding type \"" + member.type->toString() + "\" not yet implemented.");
auto memberTypeFrom = _from.memberType(member.name);
solAssert(memberTypeFrom, "");
bool dynamicMember = memberTypeTo->isDynamicallyEncoded();
@@ -989,7 +1003,7 @@ string ABIFunctions::abiEncodingFunctionStringLiteral(
)");
templ("functionName", functionName);
- // TODO this can make use of CODECOPY for large strings once we have that in JULIA
+ // TODO this can make use of CODECOPY for large strings once we have that in Yul
size_t words = (value.size() + 31) / 32;
templ("overallSize", to_string(32 + words * 32));
templ("length", to_string(value.size()));
@@ -1188,7 +1202,8 @@ string ABIFunctions::abiDecodingFunctionCalldataArray(ArrayType const& _type)
solAssert(_type.dataStoredIn(DataLocation::CallData), "");
if (!_type.isDynamicallySized())
solAssert(_type.length() < u256("0xffffffffffffffff"), "");
- solAssert(!_type.baseType()->isDynamicallyEncoded(), "");
+ if (_type.baseType()->isDynamicallyEncoded())
+ solUnimplemented("Calldata arrays with non-value base types are not yet supported by Solidity.");
solAssert(_type.baseType()->calldataEncodedSize() < u256("0xffffffffffffffff"), "");
string functionName =
@@ -1682,6 +1697,13 @@ string ABIFunctions::createFunction(string const& _name, function<string ()> con
return _name;
}
+string ABIFunctions::createExternallyUsedFunction(string const& _name, function<string ()> const& _creator)
+{
+ string name = createFunction(_name, _creator);
+ m_externallyUsedFunctions.insert(name);
+ return name;
+}
+
size_t ABIFunctions::headSize(TypePointers const& _targetTypes)
{
size_t headSize = 0;