diff options
author | Christian <c@ethdev.com> | 2015-01-23 09:46:31 +0800 |
---|---|---|
committer | Christian <c@ethdev.com> | 2015-01-26 17:23:39 +0800 |
commit | fd5899d03806d82e228da12f8cbe151f079ea41f (patch) | |
tree | f839426ef2d921062ac8206ced3089acd318496a /Compiler.cpp | |
parent | 7ded95c776717cf96e96dffb7425c86b47ad8b0e (diff) | |
download | dexon-solidity-fd5899d03806d82e228da12f8cbe151f079ea41f.tar.gz dexon-solidity-fd5899d03806d82e228da12f8cbe151f079ea41f.tar.zst dexon-solidity-fd5899d03806d82e228da12f8cbe151f079ea41f.zip |
Modifier overrides and callgraph analysis.
Diffstat (limited to 'Compiler.cpp')
-rw-r--r-- | Compiler.cpp | 52 |
1 files changed, 32 insertions, 20 deletions
diff --git a/Compiler.cpp b/Compiler.cpp index fa8eb775..99a429bc 100644 --- a/Compiler.cpp +++ b/Compiler.cpp @@ -42,9 +42,13 @@ void Compiler::compileContract(ContractDefinition const& _contract, initializeContext(_contract, _contracts); for (ContractDefinition const* contract: _contract.getLinearizedBaseContracts()) + { for (ASTPointer<FunctionDefinition> const& function: contract->getDefinedFunctions()) if (!function->isConstructor()) m_context.addFunction(*function); + for (ASTPointer<ModifierDefinition> const& modifier: contract->getFunctionModifiers()) + m_context.addModifier(*modifier); + } appendFunctionSelector(_contract); for (ContractDefinition const* contract: _contract.getLinearizedBaseContracts()) @@ -67,6 +71,13 @@ void Compiler::initializeContext(ContractDefinition const& _contract, void Compiler::packIntoContractCreator(ContractDefinition const& _contract, CompilerContext const& _runtimeContext) { + std::vector<ContractDefinition const*> const& bases = _contract.getLinearizedBaseContracts(); + + // Make all modifiers known to the context. + for (ContractDefinition const* contract: bases) + for (ASTPointer<ModifierDefinition> const& modifier: contract->getFunctionModifiers()) + m_context.addModifier(*modifier); + // arguments for base constructors, filled in derived-to-base order map<ContractDefinition const*, vector<ASTPointer<Expression>> const*> baseArguments; set<FunctionDefinition const*> neededFunctions; @@ -74,10 +85,8 @@ void Compiler::packIntoContractCreator(ContractDefinition const& _contract, Comp // Determine the arguments that are used for the base constructors and also which functions // are needed at compile time. - std::vector<ContractDefinition const*> const& bases = _contract.getLinearizedBaseContracts(); for (ContractDefinition const* contract: bases) { - //TODO include modifiers if (FunctionDefinition const* constructor = contract->getConstructor()) nodesUsedInConstructors.insert(constructor); for (ASTPointer<InheritanceSpecifier> const& base: contract->getBaseContracts()) @@ -94,7 +103,7 @@ void Compiler::packIntoContractCreator(ContractDefinition const& _contract, Comp } } - auto overrideResolver = [&](string const& _name) -> FunctionDefinition const* + auto functionOverrideResolver = [&](string const& _name) -> FunctionDefinition const* { for (ContractDefinition const* contract: bases) for (ASTPointer<FunctionDefinition> const& function: contract->getDefinedFunctions()) @@ -102,21 +111,26 @@ void Compiler::packIntoContractCreator(ContractDefinition const& _contract, Comp return function.get(); return nullptr; }; + auto modifierOverrideResolver = [&](string const& _name) -> ModifierDefinition const* + { + return &m_context.getFunctionModifier(_name); + }; - neededFunctions = getFunctionsCalled(nodesUsedInConstructors, overrideResolver); + neededFunctions = getFunctionsCalled(nodesUsedInConstructors, functionOverrideResolver, + modifierOverrideResolver); // First add all overrides (or the functions themselves if there is no override) for (FunctionDefinition const* fun: neededFunctions) { FunctionDefinition const* override = nullptr; if (!fun->isConstructor()) - override = overrideResolver(fun->getName()); + override = functionOverrideResolver(fun->getName()); if (!!override && neededFunctions.count(override)) m_context.addFunction(*override); } // now add the rest for (FunctionDefinition const* fun: neededFunctions) - if (fun->isConstructor() || overrideResolver(fun->getName()) != fun) + if (fun->isConstructor() || functionOverrideResolver(fun->getName()) != fun) m_context.addFunction(*fun); // Call constructors in base-to-derived order. @@ -176,9 +190,10 @@ void Compiler::appendConstructorCall(FunctionDefinition const& _constructor) } set<FunctionDefinition const*> Compiler::getFunctionsCalled(set<ASTNode const*> const& _nodes, - function<FunctionDefinition const*(string const&)> const& _resolveOverrides) + function<FunctionDefinition const*(string const&)> const& _resolveFunctionOverrides, + function<ModifierDefinition const*(string const&)> const& _resolveModifierOverrides) { - CallGraph callgraph(_resolveOverrides); + CallGraph callgraph(_resolveFunctionOverrides, _resolveModifierOverrides); for (ASTNode const* node: _nodes) callgraph.addNode(*node); return callgraph.getCalls(); @@ -471,25 +486,22 @@ void Compiler::appendModifierOrFunctionCode() { ASTPointer<ModifierInvocation> const& modifierInvocation = m_currentFunction->getModifiers()[m_modifierDepth]; - // TODO get the most derived override of the modifier - ModifierDefinition const* modifier = dynamic_cast<ModifierDefinition const*>( - modifierInvocation->getName()->getReferencedDeclaration()); - solAssert(!!modifier, "Modifier not found."); - solAssert(modifier->getParameters().size() == modifierInvocation->getArguments().size(), ""); - for (unsigned i = 0; i < modifier->getParameters().size(); ++i) + ModifierDefinition const& modifier = m_context.getFunctionModifier(modifierInvocation->getName()->getName()); + solAssert(modifier.getParameters().size() == modifierInvocation->getArguments().size(), ""); + for (unsigned i = 0; i < modifier.getParameters().size(); ++i) { - m_context.addVariable(*modifier->getParameters()[i]); + m_context.addVariable(*modifier.getParameters()[i]); compileExpression(*modifierInvocation->getArguments()[i], - modifier->getParameters()[i]->getType()); + modifier.getParameters()[i]->getType()); } - for (VariableDeclaration const* localVariable: modifier->getLocalVariables()) + for (VariableDeclaration const* localVariable: modifier.getLocalVariables()) m_context.addAndInitializeVariable(*localVariable); - unsigned const c_stackSurplus = CompilerUtils::getSizeOnStack(modifier->getParameters()) + - CompilerUtils::getSizeOnStack(modifier->getLocalVariables()); + unsigned const c_stackSurplus = CompilerUtils::getSizeOnStack(modifier.getParameters()) + + CompilerUtils::getSizeOnStack(modifier.getLocalVariables()); m_stackCleanupForReturn += c_stackSurplus; - modifier->getBody().accept(*this); + modifier.getBody().accept(*this); for (unsigned i = 0; i < c_stackSurplus; ++i) m_context << eth::Instruction::POP; |