Merge pull request #9173 from ethereum/fixBoundCalldata

Fix bound functions with calldata parameters.
This commit is contained in:
chriseth
2020-06-11 13:31:30 +02:00
committed by GitHub
10 changed files with 131 additions and 12 deletions
+29 -9
View File
@@ -371,7 +371,8 @@ MemberList::MemberMap Type::boundFunctions(Type const& _type, ContractDefinition
seenFunctions.insert(function);
if (function->parameters().empty())
continue;
FunctionTypePointer fun = FunctionType(*function, FunctionType::Kind::External).asExternallyCallableFunction(true, true);
FunctionTypePointer fun =
dynamic_cast<FunctionType const&>(*function->typeViaContractName()).asBoundFunction();
if (_type.isImplicitlyConvertibleTo(*fun->selfType()))
members.emplace_back(function->name(), fun, function);
}
@@ -3453,11 +3454,32 @@ TypePointer FunctionType::copyAndSetCallOptions(bool _setGas, bool _setValue, bo
);
}
FunctionTypePointer FunctionType::asExternallyCallableFunction(bool _inLibrary, bool _bound) const
FunctionTypePointer FunctionType::asBoundFunction() const
{
if (_bound)
solAssert(!m_parameterTypes.empty(), "");
solAssert(!m_parameterTypes.empty(), "");
FunctionDefinition const* fun = dynamic_cast<FunctionDefinition const*>(m_declaration);
solAssert(fun && fun->libraryFunction(), "");
solAssert(!m_gasSet, "");
solAssert(!m_valueSet, "");
solAssert(!m_saltSet, "");
return TypeProvider::function(
m_parameterTypes,
m_returnParameterTypes,
m_parameterNames,
m_returnParameterNames,
m_kind,
m_arbitraryParameters,
m_stateMutability,
m_declaration,
m_gasSet,
m_valueSet,
m_saltSet,
true
);
}
FunctionTypePointer FunctionType::asExternallyCallableFunction(bool _inLibrary) const
{
TypePointers parameterTypes;
for (auto const& t: m_parameterTypes)
if (TypeProvider::isReferenceWithLocation(t, DataLocation::CallData))
@@ -3480,10 +3502,8 @@ FunctionTypePointer FunctionType::asExternallyCallableFunction(bool _inLibrary,
if (_inLibrary)
{
solAssert(!!m_declaration, "Declaration has to be available.");
if (!m_declaration->isPublic())
kind = Kind::Internal; // will be inlined
else
kind = Kind::DelegateCall;
solAssert(m_declaration->isPublic(), "");
kind = Kind::DelegateCall;
}
return TypeProvider::function(
@@ -3498,7 +3518,7 @@ FunctionTypePointer FunctionType::asExternallyCallableFunction(bool _inLibrary,
m_gasSet,
m_valueSet,
m_saltSet,
_bound
m_bound
);
}
+5 -2
View File
@@ -1304,13 +1304,16 @@ public:
/// of the parameters to false.
TypePointer copyAndSetCallOptions(bool _setGas, bool _setValue, bool _setSalt) const;
/// @returns a copy of this function type with the `bound` flag set to true.
/// Should only be called on library functions.
FunctionTypePointer asBoundFunction() const;
/// @returns a copy of this function type where the location of reference types is changed
/// from CallData to Memory. This is the type that would be used when the function is
/// called externally, as opposed to the parameter types that are available inside the function body.
/// Also supports variants to be used for library or bound calls.
/// @param _inLibrary if true, uses DelegateCall as location.
/// @param _bound if true, the function type is set to be bound.
FunctionTypePointer asExternallyCallableFunction(bool _inLibrary, bool _bound = false) const;
FunctionTypePointer asExternallyCallableFunction(bool _inLibrary) const;
protected:
std::vector<std::tuple<std::string, TypePointer>> makeStackItems() const override;