mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
IRGeneratorForStatements: Handle internal calls to functions from specific base contracts as static calls rather than calls via pointers
This commit is contained in:
parent
397ea18b78
commit
56a85d6cb3
@ -579,32 +579,60 @@ void IRGeneratorForStatements::endVisit(FunctionCall const& _functionCall)
|
|||||||
else
|
else
|
||||||
args.emplace_back(convert(*arguments[i], *parameterTypes[i]).commaSeparatedList());
|
args.emplace_back(convert(*arguments[i], *parameterTypes[i]).commaSeparatedList());
|
||||||
|
|
||||||
if (auto identifier = dynamic_cast<Identifier const*>(&_functionCall.expression()))
|
optional<FunctionDefinition const*> functionDef;
|
||||||
|
if (auto memberAccess = dynamic_cast<MemberAccess const*>(&_functionCall.expression()))
|
||||||
{
|
{
|
||||||
solAssert(!functionType->bound(), "");
|
solAssert(!functionType->bound(), "");
|
||||||
if (auto functionDef = dynamic_cast<FunctionDefinition const*>(identifier->annotation().referencedDeclaration))
|
|
||||||
|
functionDef = dynamic_cast<FunctionDefinition const*>(memberAccess->annotation().referencedDeclaration);
|
||||||
|
if (functionDef.value() != nullptr)
|
||||||
|
solAssert(functionType->declaration() == *memberAccess->annotation().referencedDeclaration, "");
|
||||||
|
else
|
||||||
{
|
{
|
||||||
define(_functionCall) <<
|
solAssert(dynamic_cast<VariableDeclaration const*>(memberAccess->annotation().referencedDeclaration), "");
|
||||||
m_context.enqueueFunctionForCodeGeneration(
|
solAssert(!functionType->hasDeclaration(), "");
|
||||||
functionDef->resolveVirtual(m_context.mostDerivedContract())
|
|
||||||
) <<
|
|
||||||
"(" <<
|
|
||||||
joinHumanReadable(args) <<
|
|
||||||
")\n";
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (auto identifier = dynamic_cast<Identifier const*>(&_functionCall.expression()))
|
||||||
|
{
|
||||||
|
solAssert(!functionType->bound(), "");
|
||||||
|
|
||||||
define(_functionCall) <<
|
if (auto unresolvedFunctionDef = dynamic_cast<FunctionDefinition const*>(identifier->annotation().referencedDeclaration))
|
||||||
// NOTE: internalDispatch() takes care of adding the function to function generation queue
|
{
|
||||||
m_context.internalDispatch(
|
functionDef = &unresolvedFunctionDef->resolveVirtual(m_context.mostDerivedContract());
|
||||||
TupleType(functionType->parameterTypes()).sizeOnStack(),
|
solAssert(functionType->declaration() == *identifier->annotation().referencedDeclaration, "");
|
||||||
TupleType(functionType->returnParameterTypes()).sizeOnStack()
|
}
|
||||||
) <<
|
else
|
||||||
"(" <<
|
{
|
||||||
IRVariable(_functionCall.expression()).part("functionIdentifier").name() <<
|
functionDef = nullptr;
|
||||||
joinHumanReadablePrefixed(args) <<
|
solAssert(dynamic_cast<VariableDeclaration const*>(identifier->annotation().referencedDeclaration), "");
|
||||||
")\n";
|
solAssert(!functionType->hasDeclaration(), "");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
// Not a simple expression like x or A.x
|
||||||
|
functionDef = nullptr;
|
||||||
|
|
||||||
|
solAssert(functionDef.has_value(), "");
|
||||||
|
solAssert(functionDef.value() == nullptr || functionDef.value()->isImplemented(), "");
|
||||||
|
|
||||||
|
if (functionDef.value() != nullptr)
|
||||||
|
define(_functionCall) <<
|
||||||
|
m_context.enqueueFunctionForCodeGeneration(*functionDef.value()) <<
|
||||||
|
"(" <<
|
||||||
|
joinHumanReadable(args) <<
|
||||||
|
")\n";
|
||||||
|
else
|
||||||
|
define(_functionCall) <<
|
||||||
|
// NOTE: internalDispatch() takes care of adding the function to function generation queue
|
||||||
|
m_context.internalDispatch(
|
||||||
|
TupleType(functionType->parameterTypes()).sizeOnStack(),
|
||||||
|
TupleType(functionType->returnParameterTypes()).sizeOnStack()
|
||||||
|
) <<
|
||||||
|
"(" <<
|
||||||
|
IRVariable(_functionCall.expression()).part("functionIdentifier").name() <<
|
||||||
|
joinHumanReadablePrefixed(args) <<
|
||||||
|
")\n";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case FunctionType::Kind::External:
|
case FunctionType::Kind::External:
|
||||||
|
@ -34,6 +34,8 @@ contract Child is Base {
|
|||||||
BaseBase.init(c, d);
|
BaseBase.init(c, d);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// ====
|
||||||
|
// compileViaYul: also
|
||||||
// ----
|
// ----
|
||||||
// x() -> 0
|
// x() -> 0
|
||||||
// y() -> 0
|
// y() -> 0
|
||||||
|
@ -18,6 +18,8 @@ contract Child is Base {
|
|||||||
Base.init(c, d);
|
Base.init(c, d);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// ====
|
||||||
|
// compileViaYul: also
|
||||||
// ----
|
// ----
|
||||||
// x() -> 0
|
// x() -> 0
|
||||||
// y() -> 0
|
// y() -> 0
|
||||||
|
Loading…
Reference in New Issue
Block a user