|
|
|
@@ -811,7 +811,6 @@ bool IRGeneratorForStatements::visit(FunctionCall const& _functionCall)
|
|
|
|
|
if (
|
|
|
|
|
functionType &&
|
|
|
|
|
functionType->kind() == FunctionType::Kind::Internal &&
|
|
|
|
|
!functionType->bound() &&
|
|
|
|
|
IRHelpers::referencedFunctionDeclaration(_functionCall.expression())
|
|
|
|
|
)
|
|
|
|
|
m_context.internalFunctionCalledDirectly(_functionCall.expression());
|
|
|
|
@@ -888,8 +887,6 @@ void IRGeneratorForStatements::endVisit(FunctionCall const& _functionCall)
|
|
|
|
|
solAssert(functionType->kind() == FunctionType::Kind::Internal || functionType->kind() == FunctionType::Kind::DelegateCall, "");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
solAssert(!functionType->bound(), "");
|
|
|
|
|
|
|
|
|
|
switch (functionType->kind())
|
|
|
|
|
{
|
|
|
|
@@ -924,19 +921,17 @@ void IRGeneratorForStatements::endVisit(FunctionCall const& _functionCall)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
solAssert(functionDef && functionDef->isImplemented(), "");
|
|
|
|
|
solAssert(
|
|
|
|
|
functionDef->parameters().size() == arguments.size() + (functionType->bound() ? 1 : 0),
|
|
|
|
|
""
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
solAssert(!functionType->takesArbitraryParameters(), "");
|
|
|
|
|
|
|
|
|
|
vector<string> args;
|
|
|
|
|
if (functionType->bound())
|
|
|
|
|
{
|
|
|
|
|
solAssert(memberAccess && functionDef, "");
|
|
|
|
|
solAssert(functionDef->parameters().size() == arguments.size() + 1, "");
|
|
|
|
|
args += convert(memberAccess->expression(), *functionDef->parameters()[0]->type()).stackSlots();
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
solAssert(!functionDef || functionDef->parameters().size() == arguments.size(), "");
|
|
|
|
|
args += IRVariable(_functionCall.expression()).part("self").stackSlots();
|
|
|
|
|
|
|
|
|
|
for (size_t i = 0; i < arguments.size(); ++i)
|
|
|
|
|
args += convert(*arguments[i], *parameterTypes[i]).stackSlots();
|
|
|
|
@@ -1580,6 +1575,23 @@ void IRGeneratorForStatements::endVisit(MemberAccess const& _memberAccess)
|
|
|
|
|
Type::Category::Array,
|
|
|
|
|
Type::Category::FixedBytes,
|
|
|
|
|
}).count(objectCategory) > 0, "");
|
|
|
|
|
|
|
|
|
|
define(IRVariable(_memberAccess).part("self"), _memberAccess.expression());
|
|
|
|
|
auto const& functionDefinition = dynamic_cast<FunctionDefinition const&>(memberFunctionType->declaration());
|
|
|
|
|
solAssert(*_memberAccess.annotation().requiredLookup == VirtualLookup::Static, "");
|
|
|
|
|
if (memberFunctionType->kind() == FunctionType::Kind::Internal)
|
|
|
|
|
{
|
|
|
|
|
define(IRVariable(_memberAccess).part("functionIdentifier")) << to_string(functionDefinition.id()) << "\n";
|
|
|
|
|
m_context.internalFunctionAccessed(_memberAccess, functionDefinition);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
solAssert(memberFunctionType->kind() == FunctionType::Kind::DelegateCall, "");
|
|
|
|
|
auto contract = dynamic_cast<ContractDefinition const*>(functionDefinition.scope());
|
|
|
|
|
solAssert(contract && contract->isLibrary(), "");
|
|
|
|
|
define(IRVariable(_memberAccess).part("address")) << linkerSymbol(*contract) << "\n";
|
|
|
|
|
define(IRVariable(_memberAccess).part("functionSelector")) << memberFunctionType->externalIdentifier();
|
|
|
|
|
}
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -2283,15 +2295,21 @@ void IRGeneratorForStatements::appendExternalFunctionCall(
|
|
|
|
|
"Can only be used for regular external calls."
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
solUnimplementedAssert(!funType.bound(), "");
|
|
|
|
|
|
|
|
|
|
bool const isDelegateCall = funKind == FunctionType::Kind::DelegateCall;
|
|
|
|
|
bool const useStaticCall = funType.stateMutability() <= StateMutability::View && m_context.evmVersion().hasStaticCall();
|
|
|
|
|
|
|
|
|
|
ReturnInfo const returnInfo{m_context.evmVersion(), funType};
|
|
|
|
|
|
|
|
|
|
TypePointers parameterTypes = funType.parameterTypes();
|
|
|
|
|
TypePointers argumentTypes;
|
|
|
|
|
vector<string> argumentStrings;
|
|
|
|
|
if (funType.bound())
|
|
|
|
|
{
|
|
|
|
|
parameterTypes.insert(parameterTypes.begin(), funType.selfType());
|
|
|
|
|
argumentTypes.emplace_back(funType.selfType());
|
|
|
|
|
argumentStrings += IRVariable(_functionCall.expression()).part("self").stackSlots();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (auto const& arg: _arguments)
|
|
|
|
|
{
|
|
|
|
|
argumentTypes.emplace_back(&type(*arg));
|
|
|
|
@@ -2370,7 +2388,7 @@ void IRGeneratorForStatements::appendExternalFunctionCall(
|
|
|
|
|
bool encodeForLibraryCall = funKind == FunctionType::Kind::DelegateCall;
|
|
|
|
|
|
|
|
|
|
solAssert(funType.padArguments(), "");
|
|
|
|
|
templ("encodeArgs", m_context.abiFunctions().tupleEncoder(argumentTypes, funType.parameterTypes(), encodeForLibraryCall));
|
|
|
|
|
templ("encodeArgs", m_context.abiFunctions().tupleEncoder(argumentTypes, parameterTypes, encodeForLibraryCall));
|
|
|
|
|
templ("argumentString", joinHumanReadablePrefixed(argumentStrings));
|
|
|
|
|
|
|
|
|
|
solAssert(!isDelegateCall || !funType.valueSet(), "Value set for delegatecall");
|
|
|
|
|