aboutsummaryrefslogtreecommitdiffstats
path: root/libsolidity/codegen
diff options
context:
space:
mode:
authorchriseth <chris@ethereum.org>2018-03-08 18:17:08 +0800
committerAlex Beregszaszi <alex@rtfs.hu>2018-03-27 11:00:12 +0800
commit0a67d616db73c912fd16186f97be6ff2d9447975 (patch)
treef671dfbd7af8c99235efa0e2a7865aba3b80e36b /libsolidity/codegen
parentf8f50e14d24a85da2775662698db54a73905bd44 (diff)
downloaddexon-solidity-0a67d616db73c912fd16186f97be6ff2d9447975.tar
dexon-solidity-0a67d616db73c912fd16186f97be6ff2d9447975.tar.gz
dexon-solidity-0a67d616db73c912fd16186f97be6ff2d9447975.tar.bz2
dexon-solidity-0a67d616db73c912fd16186f97be6ff2d9447975.tar.lz
dexon-solidity-0a67d616db73c912fd16186f97be6ff2d9447975.tar.xz
dexon-solidity-0a67d616db73c912fd16186f97be6ff2d9447975.tar.zst
dexon-solidity-0a67d616db73c912fd16186f97be6ff2d9447975.zip
Use shortcut for internal function calls to avoid runtime reference.
Diffstat (limited to 'libsolidity/codegen')
-rw-r--r--libsolidity/codegen/ExpressionCompiler.cpp24
1 files changed, 23 insertions, 1 deletions
diff --git a/libsolidity/codegen/ExpressionCompiler.cpp b/libsolidity/codegen/ExpressionCompiler.cpp
index 37069c3e..f4ca9dff 100644
--- a/libsolidity/codegen/ExpressionCompiler.cpp
+++ b/libsolidity/codegen/ExpressionCompiler.cpp
@@ -518,7 +518,25 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall)
arguments[i]->accept(*this);
utils().convertType(*arguments[i]->annotation().type, *function.parameterTypes()[i]);
}
- _functionCall.expression().accept(*this);
+
+ {
+ bool shortcutTaken = false;
+ if (auto identifier = dynamic_cast<Identifier const*>(&_functionCall.expression()))
+ if (auto functionDef = dynamic_cast<FunctionDefinition const*>(identifier->annotation().referencedDeclaration))
+ {
+ // Do not directly visit the identifier, because this way, we can avoid
+ // the runtime entry label to be created at the creation time context.
+ CompilerContext::LocationSetter locationSetter2(m_context, *identifier);
+ m_context << m_context.functionEntryLabel(m_context.resolveVirtualFunction(*functionDef)).pushTag();
+ if (m_context.runtimeContext())
+ utils().leftShiftNumberOnStack(32);
+ shortcutTaken = true;
+ }
+
+ if (!shortcutTaken)
+ _functionCall.expression().accept(*this);
+ }
+
unsigned parameterSize = CompilerUtils::sizeOnStack(function.parameterTypes());
if (function.bound())
{
@@ -1359,6 +1377,10 @@ void ExpressionCompiler::endVisit(Identifier const& _identifier)
}
}
else if (FunctionDefinition const* functionDef = dynamic_cast<FunctionDefinition const*>(declaration))
+ // If the identifier is called right away, this code is executed in visit(FunctionCall...), because
+ // we want to avoid having a reference to the runtime function entry point in the
+ // constructor context, since this would force the compiler to include unreferenced
+ // internal functions in the runtime contex.
utils().pushCombinedFunctionEntryLabel(m_context.resolveVirtualFunction(*functionDef));
else if (auto variable = dynamic_cast<VariableDeclaration const*>(declaration))
appendVariable(*variable, static_cast<Expression const&>(_identifier));