Fix internal function calls.

This commit is contained in:
chriseth 2019-05-09 12:00:23 +02:00
parent 45ee3fc007
commit 60a42f58a0
3 changed files with 13 additions and 5 deletions

View File

@ -103,8 +103,6 @@ string IRGenerationContext::variable(Expression const& _expression)
string IRGenerationContext::internalDispatch(size_t _in, size_t _out)
{
// TODO can we limit the generated functions to only those visited
// in the expression context? What about creation / runtime context?
string funName = "dispatch_internal_in_" + to_string(_in) + "_out_" + to_string(_out);
return m_functions->createFunction(funName, [&]() {
Whiskers templ(R"(

View File

@ -94,12 +94,21 @@ string IRGenerator::generate(ContractDefinition const& _contract)
t("memoryInit", memoryInit());
t("constructor", _contract.constructor() ? constructorCode(*_contract.constructor()) : "");
t("deploy", deployCode(_contract));
// We generate code for all functions and rely on the optimizer to remove them again
// TODO it would probably be better to only generate functions when internalDispatch or
// virtualFunctionName is called - same below.
for (auto const* contract: _contract.annotation().linearizedBaseContracts)
for (auto const* fun: contract->definedFunctions())
generateFunction(*fun);
t("functions", m_context.functionCollector()->requestedFunctions());
resetContext(_contract);
m_context.setInheritanceHierarchy(_contract.annotation().linearizedBaseContracts);
t("RuntimeObject", runtimeObjectName(_contract));
t("dispatch", dispatchRoutine(_contract));
for (auto const* contract: _contract.annotation().linearizedBaseContracts)
for (auto const* fun: contract->definedFunctions())
generateFunction(*fun);
t("runtimeFunctions", m_context.functionCollector()->requestedFunctions());
return t.render();
}

View File

@ -375,7 +375,6 @@ void IRGeneratorForStatements::endVisit(FunctionCall const& _functionCall)
solAssert(!functionType->bound(), "");
if (auto functionDef = dynamic_cast<FunctionDefinition const*>(identifier->annotation().referencedDeclaration))
{
// @TODO The function can very well return multiple vars.
defineExpression(_functionCall) <<
m_context.virtualFunctionName(*functionDef) <<
"(" <<
@ -385,7 +384,6 @@ void IRGeneratorForStatements::endVisit(FunctionCall const& _functionCall)
}
}
// @TODO The function can very well return multiple vars.
args = vector<string>{m_context.variable(_functionCall.expression())} + args;
defineExpression(_functionCall) <<
m_context.internalDispatch(functionType->parameterTypes().size(), functionType->returnParameterTypes().size()) <<
@ -786,7 +784,10 @@ string IRGeneratorForStatements::expressionAsType(Expression const& _expression,
ostream& IRGeneratorForStatements::defineExpression(Expression const& _expression)
{
return m_code << "let " << m_context.variable(_expression) << " := ";
string vars = m_context.variable(_expression);
if (!vars.empty())
m_code << "let " << move(vars) << " := ";
return m_code;
}
void IRGeneratorForStatements::appendAndOrOperatorCode(BinaryOperation const& _binOp)