mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Provide ABI encoding options as single struct parameter.
This commit is contained in:
parent
8f694d5119
commit
7a69455c13
@ -39,14 +39,19 @@ string ABIFunctions::tupleEncoder(
|
|||||||
bool _encodeAsLibraryTypes
|
bool _encodeAsLibraryTypes
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
EncodingOptions options;
|
||||||
|
options.encodeAsLibraryTypes = _encodeAsLibraryTypes;
|
||||||
|
options.encodeFunctionFromStack = true;
|
||||||
|
options.padded = true;
|
||||||
|
options.dynamicInplace = false;
|
||||||
|
|
||||||
string functionName = string("abi_encode_tuple_");
|
string functionName = string("abi_encode_tuple_");
|
||||||
for (auto const& t: _givenTypes)
|
for (auto const& t: _givenTypes)
|
||||||
functionName += t->identifier() + "_";
|
functionName += t->identifier() + "_";
|
||||||
functionName += "_to_";
|
functionName += "_to_";
|
||||||
for (auto const& t: _targetTypes)
|
for (auto const& t: _targetTypes)
|
||||||
functionName += t->identifier() + "_";
|
functionName += t->identifier() + "_";
|
||||||
if (_encodeAsLibraryTypes)
|
functionName += options.toFunctionNameSuffix();
|
||||||
functionName += "_library";
|
|
||||||
|
|
||||||
return createExternallyUsedFunction(functionName, [&]() {
|
return createExternallyUsedFunction(functionName, [&]() {
|
||||||
solAssert(!_givenTypes.empty(), "");
|
solAssert(!_givenTypes.empty(), "");
|
||||||
@ -90,7 +95,7 @@ string ABIFunctions::tupleEncoder(
|
|||||||
);
|
);
|
||||||
elementTempl("values", valueNames);
|
elementTempl("values", valueNames);
|
||||||
elementTempl("pos", to_string(headPos));
|
elementTempl("pos", to_string(headPos));
|
||||||
elementTempl("abiEncode", abiEncodingFunction(*_givenTypes[i], *_targetTypes[i], _encodeAsLibraryTypes, true));
|
elementTempl("abiEncode", abiEncodingFunction(*_givenTypes[i], *_targetTypes[i], options));
|
||||||
encodeElements += elementTempl.render();
|
encodeElements += elementTempl.render();
|
||||||
headPos += dynamic ? 0x20 : _targetTypes[i]->calldataEncodedSize();
|
headPos += dynamic ? 0x20 : _targetTypes[i]->calldataEncodedSize();
|
||||||
}
|
}
|
||||||
@ -184,6 +189,20 @@ pair<string, set<string>> ABIFunctions::requestedFunctions()
|
|||||||
return make_pair(result, std::move(m_externallyUsedFunctions));
|
return make_pair(result, std::move(m_externallyUsedFunctions));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
string ABIFunctions::EncodingOptions::toFunctionNameSuffix() const
|
||||||
|
{
|
||||||
|
string suffix;
|
||||||
|
if (!padded)
|
||||||
|
suffix += "_nonPadded";
|
||||||
|
if (dynamicInplace)
|
||||||
|
suffix += "_inplace";
|
||||||
|
if (encodeFunctionFromStack)
|
||||||
|
suffix += "_fromStack";
|
||||||
|
if (encodeAsLibraryTypes)
|
||||||
|
suffix += "_library";
|
||||||
|
return suffix;
|
||||||
|
}
|
||||||
|
|
||||||
string ABIFunctions::cleanupFunction(Type const& _type, bool _revertOnFailure)
|
string ABIFunctions::cleanupFunction(Type const& _type, bool _revertOnFailure)
|
||||||
{
|
{
|
||||||
string functionName = string("cleanup_") + (_revertOnFailure ? "revert_" : "assert_") + _type.identifier();
|
string functionName = string("cleanup_") + (_revertOnFailure ? "revert_" : "assert_") + _type.identifier();
|
||||||
@ -490,32 +509,31 @@ string ABIFunctions::splitExternalFunctionIdFunction()
|
|||||||
string ABIFunctions::abiEncodingFunction(
|
string ABIFunctions::abiEncodingFunction(
|
||||||
Type const& _from,
|
Type const& _from,
|
||||||
Type const& _to,
|
Type const& _to,
|
||||||
bool _encodeAsLibraryTypes,
|
EncodingOptions const& _options
|
||||||
bool _fromStack
|
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
TypePointer toInterface = _to.fullEncodingType(_encodeAsLibraryTypes, true, false);
|
TypePointer toInterface = _to.fullEncodingType(_options.encodeAsLibraryTypes, true, false);
|
||||||
solUnimplementedAssert(toInterface, "Encoding type \"" + _to.toString() + "\" not yet implemented.");
|
solUnimplementedAssert(toInterface, "Encoding type \"" + _to.toString() + "\" not yet implemented.");
|
||||||
Type const& to = *toInterface;
|
Type const& to = *toInterface;
|
||||||
|
|
||||||
if (_from.category() == Type::Category::StringLiteral)
|
if (_from.category() == Type::Category::StringLiteral)
|
||||||
return abiEncodingFunctionStringLiteral(_from, to, _encodeAsLibraryTypes);
|
return abiEncodingFunctionStringLiteral(_from, to, _options);
|
||||||
else if (auto toArray = dynamic_cast<ArrayType const*>(&to))
|
else if (auto toArray = dynamic_cast<ArrayType const*>(&to))
|
||||||
{
|
{
|
||||||
solAssert(_from.category() == Type::Category::Array, "");
|
solAssert(_from.category() == Type::Category::Array, "");
|
||||||
solAssert(to.dataStoredIn(DataLocation::Memory), "");
|
solAssert(to.dataStoredIn(DataLocation::Memory), "");
|
||||||
ArrayType const& fromArray = dynamic_cast<ArrayType const&>(_from);
|
ArrayType const& fromArray = dynamic_cast<ArrayType const&>(_from);
|
||||||
if (fromArray.location() == DataLocation::CallData)
|
if (fromArray.location() == DataLocation::CallData)
|
||||||
return abiEncodingFunctionCalldataArray(fromArray, *toArray, _encodeAsLibraryTypes);
|
return abiEncodingFunctionCalldataArray(fromArray, *toArray, _options);
|
||||||
else if (!fromArray.isByteArray() && (
|
else if (!fromArray.isByteArray() && (
|
||||||
fromArray.location() == DataLocation::Memory ||
|
fromArray.location() == DataLocation::Memory ||
|
||||||
fromArray.baseType()->storageBytes() > 16
|
fromArray.baseType()->storageBytes() > 16
|
||||||
))
|
))
|
||||||
return abiEncodingFunctionSimpleArray(fromArray, *toArray, _encodeAsLibraryTypes);
|
return abiEncodingFunctionSimpleArray(fromArray, *toArray, _options);
|
||||||
else if (fromArray.location() == DataLocation::Memory)
|
else if (fromArray.location() == DataLocation::Memory)
|
||||||
return abiEncodingFunctionMemoryByteArray(fromArray, *toArray, _encodeAsLibraryTypes);
|
return abiEncodingFunctionMemoryByteArray(fromArray, *toArray, _options);
|
||||||
else if (fromArray.location() == DataLocation::Storage)
|
else if (fromArray.location() == DataLocation::Storage)
|
||||||
return abiEncodingFunctionCompactStorageArray(fromArray, *toArray, _encodeAsLibraryTypes);
|
return abiEncodingFunctionCompactStorageArray(fromArray, *toArray, _options);
|
||||||
else
|
else
|
||||||
solAssert(false, "");
|
solAssert(false, "");
|
||||||
}
|
}
|
||||||
@ -523,14 +541,13 @@ string ABIFunctions::abiEncodingFunction(
|
|||||||
{
|
{
|
||||||
StructType const* fromStruct = dynamic_cast<StructType const*>(&_from);
|
StructType const* fromStruct = dynamic_cast<StructType const*>(&_from);
|
||||||
solAssert(fromStruct, "");
|
solAssert(fromStruct, "");
|
||||||
return abiEncodingFunctionStruct(*fromStruct, *toStruct, _encodeAsLibraryTypes);
|
return abiEncodingFunctionStruct(*fromStruct, *toStruct, _options);
|
||||||
}
|
}
|
||||||
else if (_from.category() == Type::Category::Function)
|
else if (_from.category() == Type::Category::Function)
|
||||||
return abiEncodingFunctionFunctionType(
|
return abiEncodingFunctionFunctionType(
|
||||||
dynamic_cast<FunctionType const&>(_from),
|
dynamic_cast<FunctionType const&>(_from),
|
||||||
to,
|
to,
|
||||||
_encodeAsLibraryTypes,
|
_options
|
||||||
_fromStack
|
|
||||||
);
|
);
|
||||||
|
|
||||||
solAssert(_from.sizeOnStack() == 1, "");
|
solAssert(_from.sizeOnStack() == 1, "");
|
||||||
@ -541,7 +558,7 @@ string ABIFunctions::abiEncodingFunction(
|
|||||||
_from.identifier() +
|
_from.identifier() +
|
||||||
"_to_" +
|
"_to_" +
|
||||||
to.identifier() +
|
to.identifier() +
|
||||||
(_encodeAsLibraryTypes ? "_library" : "");
|
_options.toFunctionNameSuffix();
|
||||||
return createFunction(functionName, [&]() {
|
return createFunction(functionName, [&]() {
|
||||||
solAssert(!to.isDynamicallyEncoded(), "");
|
solAssert(!to.isDynamicallyEncoded(), "");
|
||||||
|
|
||||||
@ -556,7 +573,7 @@ string ABIFunctions::abiEncodingFunction(
|
|||||||
{
|
{
|
||||||
// special case: convert storage reference type to value type - this is only
|
// special case: convert storage reference type to value type - this is only
|
||||||
// possible for library calls where we just forward the storage reference
|
// possible for library calls where we just forward the storage reference
|
||||||
solAssert(_encodeAsLibraryTypes, "");
|
solAssert(_options.encodeAsLibraryTypes, "");
|
||||||
solAssert(to == IntegerType::uint256(), "");
|
solAssert(to == IntegerType::uint256(), "");
|
||||||
templ("cleanupConvert", "value");
|
templ("cleanupConvert", "value");
|
||||||
}
|
}
|
||||||
@ -574,7 +591,7 @@ string ABIFunctions::abiEncodingFunction(
|
|||||||
string ABIFunctions::abiEncodingFunctionCalldataArray(
|
string ABIFunctions::abiEncodingFunctionCalldataArray(
|
||||||
Type const& _from,
|
Type const& _from,
|
||||||
Type const& _to,
|
Type const& _to,
|
||||||
bool _encodeAsLibraryTypes
|
EncodingOptions const& _options
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
solAssert(_to.isDynamicallySized(), "");
|
solAssert(_to.isDynamicallySized(), "");
|
||||||
@ -596,7 +613,7 @@ string ABIFunctions::abiEncodingFunctionCalldataArray(
|
|||||||
_from.identifier() +
|
_from.identifier() +
|
||||||
"_to_" +
|
"_to_" +
|
||||||
_to.identifier() +
|
_to.identifier() +
|
||||||
(_encodeAsLibraryTypes ? "_library" : "");
|
_options.toFunctionNameSuffix();
|
||||||
return createFunction(functionName, [&]() {
|
return createFunction(functionName, [&]() {
|
||||||
solUnimplementedAssert(fromArrayType.isByteArray(), "Only byte arrays can be encoded from calldata currently.");
|
solUnimplementedAssert(fromArrayType.isByteArray(), "Only byte arrays can be encoded from calldata currently.");
|
||||||
// TODO if this is not a byte array, we might just copy byte-by-byte anyway,
|
// TODO if this is not a byte array, we might just copy byte-by-byte anyway,
|
||||||
@ -622,7 +639,7 @@ string ABIFunctions::abiEncodingFunctionCalldataArray(
|
|||||||
string ABIFunctions::abiEncodingFunctionSimpleArray(
|
string ABIFunctions::abiEncodingFunctionSimpleArray(
|
||||||
ArrayType const& _from,
|
ArrayType const& _from,
|
||||||
ArrayType const& _to,
|
ArrayType const& _to,
|
||||||
bool _encodeAsLibraryTypes
|
EncodingOptions const& _options
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
string functionName =
|
string functionName =
|
||||||
@ -630,7 +647,7 @@ string ABIFunctions::abiEncodingFunctionSimpleArray(
|
|||||||
_from.identifier() +
|
_from.identifier() +
|
||||||
"_to_" +
|
"_to_" +
|
||||||
_to.identifier() +
|
_to.identifier() +
|
||||||
(_encodeAsLibraryTypes ? "_library" : "");
|
_options.toFunctionNameSuffix();
|
||||||
|
|
||||||
solAssert(_from.isDynamicallySized() == _to.isDynamicallySized(), "");
|
solAssert(_from.isDynamicallySized() == _to.isDynamicallySized(), "");
|
||||||
solAssert(_from.length() == _to.length(), "");
|
solAssert(_from.length() == _to.length(), "");
|
||||||
@ -691,11 +708,13 @@ string ABIFunctions::abiEncodingFunctionSimpleArray(
|
|||||||
templ("storeLength", "");
|
templ("storeLength", "");
|
||||||
templ("dataAreaFun", arrayDataAreaFunction(_from));
|
templ("dataAreaFun", arrayDataAreaFunction(_from));
|
||||||
templ("elementEncodedSize", toCompactHexWithPrefix(_to.baseType()->calldataEncodedSize()));
|
templ("elementEncodedSize", toCompactHexWithPrefix(_to.baseType()->calldataEncodedSize()));
|
||||||
|
|
||||||
|
EncodingOptions subOptions(_options);
|
||||||
|
subOptions.encodeFunctionFromStack = false;
|
||||||
templ("encodeToMemoryFun", abiEncodingFunction(
|
templ("encodeToMemoryFun", abiEncodingFunction(
|
||||||
*_from.baseType(),
|
*_from.baseType(),
|
||||||
*_to.baseType(),
|
*_to.baseType(),
|
||||||
_encodeAsLibraryTypes,
|
subOptions
|
||||||
false
|
|
||||||
));
|
));
|
||||||
templ("arrayElementAccess", inMemory ? "mload(srcPtr)" : _from.baseType()->isValueType() ? "sload(srcPtr)" : "srcPtr" );
|
templ("arrayElementAccess", inMemory ? "mload(srcPtr)" : _from.baseType()->isValueType() ? "sload(srcPtr)" : "srcPtr" );
|
||||||
templ("nextArrayElement", nextArrayElementFunction(_from));
|
templ("nextArrayElement", nextArrayElementFunction(_from));
|
||||||
@ -706,7 +725,7 @@ string ABIFunctions::abiEncodingFunctionSimpleArray(
|
|||||||
string ABIFunctions::abiEncodingFunctionMemoryByteArray(
|
string ABIFunctions::abiEncodingFunctionMemoryByteArray(
|
||||||
ArrayType const& _from,
|
ArrayType const& _from,
|
||||||
ArrayType const& _to,
|
ArrayType const& _to,
|
||||||
bool _encodeAsLibraryTypes
|
EncodingOptions const& _options
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
string functionName =
|
string functionName =
|
||||||
@ -714,7 +733,7 @@ string ABIFunctions::abiEncodingFunctionMemoryByteArray(
|
|||||||
_from.identifier() +
|
_from.identifier() +
|
||||||
"_to_" +
|
"_to_" +
|
||||||
_to.identifier() +
|
_to.identifier() +
|
||||||
(_encodeAsLibraryTypes ? "_library" : "");
|
_options.toFunctionNameSuffix();
|
||||||
|
|
||||||
solAssert(_from.isDynamicallySized() == _to.isDynamicallySized(), "");
|
solAssert(_from.isDynamicallySized() == _to.isDynamicallySized(), "");
|
||||||
solAssert(_from.length() == _to.length(), "");
|
solAssert(_from.length() == _to.length(), "");
|
||||||
@ -742,7 +761,7 @@ string ABIFunctions::abiEncodingFunctionMemoryByteArray(
|
|||||||
string ABIFunctions::abiEncodingFunctionCompactStorageArray(
|
string ABIFunctions::abiEncodingFunctionCompactStorageArray(
|
||||||
ArrayType const& _from,
|
ArrayType const& _from,
|
||||||
ArrayType const& _to,
|
ArrayType const& _to,
|
||||||
bool _encodeAsLibraryTypes
|
EncodingOptions const& _options
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
string functionName =
|
string functionName =
|
||||||
@ -750,7 +769,7 @@ string ABIFunctions::abiEncodingFunctionCompactStorageArray(
|
|||||||
_from.identifier() +
|
_from.identifier() +
|
||||||
"_to_" +
|
"_to_" +
|
||||||
_to.identifier() +
|
_to.identifier() +
|
||||||
(_encodeAsLibraryTypes ? "_library" : "");
|
_options.toFunctionNameSuffix();
|
||||||
|
|
||||||
solAssert(_from.isDynamicallySized() == _to.isDynamicallySized(), "");
|
solAssert(_from.isDynamicallySized() == _to.isDynamicallySized(), "");
|
||||||
solAssert(_from.length() == _to.length(), "");
|
solAssert(_from.length() == _to.length(), "");
|
||||||
@ -840,11 +859,13 @@ string ABIFunctions::abiEncodingFunctionCompactStorageArray(
|
|||||||
templ("itemsPerSlot", to_string(itemsPerSlot));
|
templ("itemsPerSlot", to_string(itemsPerSlot));
|
||||||
string elementEncodedSize = toCompactHexWithPrefix(_to.baseType()->calldataEncodedSize());
|
string elementEncodedSize = toCompactHexWithPrefix(_to.baseType()->calldataEncodedSize());
|
||||||
templ("elementEncodedSize", elementEncodedSize);
|
templ("elementEncodedSize", elementEncodedSize);
|
||||||
|
|
||||||
|
EncodingOptions subOptions(_options);
|
||||||
|
subOptions.encodeFunctionFromStack = false;
|
||||||
string encodeToMemoryFun = abiEncodingFunction(
|
string encodeToMemoryFun = abiEncodingFunction(
|
||||||
*_from.baseType(),
|
*_from.baseType(),
|
||||||
*_to.baseType(),
|
*_to.baseType(),
|
||||||
_encodeAsLibraryTypes,
|
subOptions
|
||||||
false
|
|
||||||
);
|
);
|
||||||
templ("encodeToMemoryFun", encodeToMemoryFun);
|
templ("encodeToMemoryFun", encodeToMemoryFun);
|
||||||
std::vector<std::map<std::string, std::string>> items(itemsPerSlot);
|
std::vector<std::map<std::string, std::string>> items(itemsPerSlot);
|
||||||
@ -859,7 +880,7 @@ string ABIFunctions::abiEncodingFunctionCompactStorageArray(
|
|||||||
string ABIFunctions::abiEncodingFunctionStruct(
|
string ABIFunctions::abiEncodingFunctionStruct(
|
||||||
StructType const& _from,
|
StructType const& _from,
|
||||||
StructType const& _to,
|
StructType const& _to,
|
||||||
bool _encodeAsLibraryTypes
|
EncodingOptions const& _options
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
string functionName =
|
string functionName =
|
||||||
@ -867,7 +888,7 @@ string ABIFunctions::abiEncodingFunctionStruct(
|
|||||||
_from.identifier() +
|
_from.identifier() +
|
||||||
"_to_" +
|
"_to_" +
|
||||||
_to.identifier() +
|
_to.identifier() +
|
||||||
(_encodeAsLibraryTypes ? "_library" : "");
|
_options.toFunctionNameSuffix();
|
||||||
|
|
||||||
solUnimplementedAssert(!_from.dataStoredIn(DataLocation::CallData), "Encoding struct from calldata is not yet supported.");
|
solUnimplementedAssert(!_from.dataStoredIn(DataLocation::CallData), "Encoding struct from calldata is not yet supported.");
|
||||||
solAssert(&_from.structDefinition() == &_to.structDefinition(), "");
|
solAssert(&_from.structDefinition() == &_to.structDefinition(), "");
|
||||||
@ -904,7 +925,7 @@ string ABIFunctions::abiEncodingFunctionStruct(
|
|||||||
solAssert(member.type, "");
|
solAssert(member.type, "");
|
||||||
if (!member.type->canLiveOutsideStorage())
|
if (!member.type->canLiveOutsideStorage())
|
||||||
continue;
|
continue;
|
||||||
TypePointer memberTypeTo = member.type->fullEncodingType(_encodeAsLibraryTypes, true, false);
|
TypePointer memberTypeTo = member.type->fullEncodingType(_options.encodeAsLibraryTypes, true, false);
|
||||||
solUnimplementedAssert(memberTypeTo, "Encoding type \"" + member.type->toString() + "\" not yet implemented.");
|
solUnimplementedAssert(memberTypeTo, "Encoding type \"" + member.type->toString() + "\" not yet implemented.");
|
||||||
auto memberTypeFrom = _from.memberType(member.name);
|
auto memberTypeFrom = _from.memberType(member.name);
|
||||||
solAssert(memberTypeFrom, "");
|
solAssert(memberTypeFrom, "");
|
||||||
@ -958,7 +979,10 @@ string ABIFunctions::abiEncodingFunctionStruct(
|
|||||||
}
|
}
|
||||||
memberTempl("encodingOffset", toCompactHexWithPrefix(encodingOffset));
|
memberTempl("encodingOffset", toCompactHexWithPrefix(encodingOffset));
|
||||||
encodingOffset += dynamicMember ? 0x20 : memberTypeTo->calldataEncodedSize();
|
encodingOffset += dynamicMember ? 0x20 : memberTypeTo->calldataEncodedSize();
|
||||||
memberTempl("abiEncode", abiEncodingFunction(*memberTypeFrom, *memberTypeTo, _encodeAsLibraryTypes, false));
|
|
||||||
|
EncodingOptions subOptions(_options);
|
||||||
|
subOptions.encodeFunctionFromStack = false;
|
||||||
|
memberTempl("abiEncode", abiEncodingFunction(*memberTypeFrom, *memberTypeTo, subOptions));
|
||||||
|
|
||||||
members.push_back({});
|
members.push_back({});
|
||||||
members.back()["encode"] = memberTempl.render();
|
members.back()["encode"] = memberTempl.render();
|
||||||
@ -973,7 +997,7 @@ string ABIFunctions::abiEncodingFunctionStruct(
|
|||||||
string ABIFunctions::abiEncodingFunctionStringLiteral(
|
string ABIFunctions::abiEncodingFunctionStringLiteral(
|
||||||
Type const& _from,
|
Type const& _from,
|
||||||
Type const& _to,
|
Type const& _to,
|
||||||
bool _encodeAsLibraryTypes
|
EncodingOptions const& _options
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
solAssert(_from.category() == Type::Category::StringLiteral, "");
|
solAssert(_from.category() == Type::Category::StringLiteral, "");
|
||||||
@ -983,7 +1007,7 @@ string ABIFunctions::abiEncodingFunctionStringLiteral(
|
|||||||
_from.identifier() +
|
_from.identifier() +
|
||||||
"_to_" +
|
"_to_" +
|
||||||
_to.identifier() +
|
_to.identifier() +
|
||||||
(_encodeAsLibraryTypes ? "_library" : "");
|
_options.toFunctionNameSuffix();
|
||||||
return createFunction(functionName, [&]() {
|
return createFunction(functionName, [&]() {
|
||||||
auto const& strType = dynamic_cast<StringLiteralType const&>(_from);
|
auto const& strType = dynamic_cast<StringLiteralType const&>(_from);
|
||||||
string const& value = strType.value();
|
string const& value = strType.value();
|
||||||
@ -1034,8 +1058,7 @@ string ABIFunctions::abiEncodingFunctionStringLiteral(
|
|||||||
string ABIFunctions::abiEncodingFunctionFunctionType(
|
string ABIFunctions::abiEncodingFunctionFunctionType(
|
||||||
FunctionType const& _from,
|
FunctionType const& _from,
|
||||||
Type const& _to,
|
Type const& _to,
|
||||||
bool _encodeAsLibraryTypes,
|
EncodingOptions const& _options
|
||||||
bool _fromStack
|
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
solAssert(_from.kind() == FunctionType::Kind::External, "");
|
solAssert(_from.kind() == FunctionType::Kind::External, "");
|
||||||
@ -1046,10 +1069,9 @@ string ABIFunctions::abiEncodingFunctionFunctionType(
|
|||||||
_from.identifier() +
|
_from.identifier() +
|
||||||
"_to_" +
|
"_to_" +
|
||||||
_to.identifier() +
|
_to.identifier() +
|
||||||
(_fromStack ? "_fromStack" : "") +
|
_options.toFunctionNameSuffix();
|
||||||
(_encodeAsLibraryTypes ? "_library" : "");
|
|
||||||
|
|
||||||
if (_fromStack)
|
if (_options.encodeFunctionFromStack)
|
||||||
return createFunction(functionName, [&]() {
|
return createFunction(functionName, [&]() {
|
||||||
return Whiskers(R"(
|
return Whiskers(R"(
|
||||||
function <functionName>(addr, function_id, pos) {
|
function <functionName>(addr, function_id, pos) {
|
||||||
@ -1716,3 +1738,4 @@ size_t ABIFunctions::headSize(TypePointers const& _targetTypes)
|
|||||||
|
|
||||||
return headSize;
|
return headSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -87,6 +87,23 @@ public:
|
|||||||
std::pair<std::string, std::set<std::string>> requestedFunctions();
|
std::pair<std::string, std::set<std::string>> requestedFunctions();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
struct EncodingOptions
|
||||||
|
{
|
||||||
|
/// Pad/signextend value types and bytes/string to multiples of 32 bytes.
|
||||||
|
bool padded = true;
|
||||||
|
/// Store arrays and structs in place without "data pointer" and do not store the length.
|
||||||
|
bool dynamicInplace = false;
|
||||||
|
/// Only for external function types: The value is a pair of address / function id instead
|
||||||
|
/// of a memory pointer to the compression representation.
|
||||||
|
bool encodeFunctionFromStack = false;
|
||||||
|
/// Encode storage pointers as storage pointers (we are targeting a library call).
|
||||||
|
bool encodeAsLibraryTypes = false;
|
||||||
|
|
||||||
|
/// @returns a string to uniquely identify the encoding options for the encoding
|
||||||
|
/// function name. Skips everything that has its default value.
|
||||||
|
std::string toFunctionNameSuffix() const;
|
||||||
|
};
|
||||||
|
|
||||||
/// @returns the name of the cleanup function for the given type and
|
/// @returns the name of the cleanup function for the given type and
|
||||||
/// adds its implementation to the requested functions.
|
/// adds its implementation to the requested functions.
|
||||||
/// @param _revertOnFailure if true, causes revert on invalid data,
|
/// @param _revertOnFailure if true, causes revert on invalid data,
|
||||||
@ -115,40 +132,39 @@ private:
|
|||||||
std::string abiEncodingFunction(
|
std::string abiEncodingFunction(
|
||||||
Type const& _givenType,
|
Type const& _givenType,
|
||||||
Type const& _targetType,
|
Type const& _targetType,
|
||||||
bool _encodeAsLibraryTypes,
|
EncodingOptions const& _options
|
||||||
bool _fromStack
|
|
||||||
);
|
);
|
||||||
/// Part of @a abiEncodingFunction for array target type and given calldata array.
|
/// Part of @a abiEncodingFunction for array target type and given calldata array.
|
||||||
std::string abiEncodingFunctionCalldataArray(
|
std::string abiEncodingFunctionCalldataArray(
|
||||||
Type const& _givenType,
|
Type const& _givenType,
|
||||||
Type const& _targetType,
|
Type const& _targetType,
|
||||||
bool _encodeAsLibraryTypes
|
EncodingOptions const& _options
|
||||||
);
|
);
|
||||||
/// Part of @a abiEncodingFunction for array target type and given memory array or
|
/// Part of @a abiEncodingFunction for array target type and given memory array or
|
||||||
/// a given storage array with one item per slot.
|
/// a given storage array with one item per slot.
|
||||||
std::string abiEncodingFunctionSimpleArray(
|
std::string abiEncodingFunctionSimpleArray(
|
||||||
ArrayType const& _givenType,
|
ArrayType const& _givenType,
|
||||||
ArrayType const& _targetType,
|
ArrayType const& _targetType,
|
||||||
bool _encodeAsLibraryTypes
|
EncodingOptions const& _options
|
||||||
);
|
);
|
||||||
std::string abiEncodingFunctionMemoryByteArray(
|
std::string abiEncodingFunctionMemoryByteArray(
|
||||||
ArrayType const& _givenType,
|
ArrayType const& _givenType,
|
||||||
ArrayType const& _targetType,
|
ArrayType const& _targetType,
|
||||||
bool _encodeAsLibraryTypes
|
EncodingOptions const& _options
|
||||||
);
|
);
|
||||||
/// Part of @a abiEncodingFunction for array target type and given storage array
|
/// Part of @a abiEncodingFunction for array target type and given storage array
|
||||||
/// where multiple items are packed into the same storage slot.
|
/// where multiple items are packed into the same storage slot.
|
||||||
std::string abiEncodingFunctionCompactStorageArray(
|
std::string abiEncodingFunctionCompactStorageArray(
|
||||||
ArrayType const& _givenType,
|
ArrayType const& _givenType,
|
||||||
ArrayType const& _targetType,
|
ArrayType const& _targetType,
|
||||||
bool _encodeAsLibraryTypes
|
EncodingOptions const& _options
|
||||||
);
|
);
|
||||||
|
|
||||||
/// Part of @a abiEncodingFunction for struct types.
|
/// Part of @a abiEncodingFunction for struct types.
|
||||||
std::string abiEncodingFunctionStruct(
|
std::string abiEncodingFunctionStruct(
|
||||||
StructType const& _givenType,
|
StructType const& _givenType,
|
||||||
StructType const& _targetType,
|
StructType const& _targetType,
|
||||||
bool _encodeAsLibraryTypes
|
EncodingOptions const& _options
|
||||||
);
|
);
|
||||||
|
|
||||||
// @returns the name of the ABI encoding function with the given type
|
// @returns the name of the ABI encoding function with the given type
|
||||||
@ -157,14 +173,13 @@ private:
|
|||||||
std::string abiEncodingFunctionStringLiteral(
|
std::string abiEncodingFunctionStringLiteral(
|
||||||
Type const& _givenType,
|
Type const& _givenType,
|
||||||
Type const& _targetType,
|
Type const& _targetType,
|
||||||
bool _encodeAsLibraryTypes
|
EncodingOptions const& _options
|
||||||
);
|
);
|
||||||
|
|
||||||
std::string abiEncodingFunctionFunctionType(
|
std::string abiEncodingFunctionFunctionType(
|
||||||
FunctionType const& _from,
|
FunctionType const& _from,
|
||||||
Type const& _to,
|
Type const& _to,
|
||||||
bool _encodeAsLibraryTypes,
|
EncodingOptions const& _options
|
||||||
bool _fromStack
|
|
||||||
);
|
);
|
||||||
|
|
||||||
/// @returns the name of the ABI decoding function for the given type
|
/// @returns the name of the ABI decoding function for the given type
|
||||||
|
Loading…
Reference in New Issue
Block a user