mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Merge branch 'sol_defaultFunction' of https://github.com/chriseth/cpp-ethereum into chriseth-sol_defaultFunction
This commit is contained in:
commit
f46df7cb92
16
AST.cpp
16
AST.cpp
@ -58,6 +58,11 @@ void ContractDefinition::checkTypeRequirements()
|
|||||||
BOOST_THROW_EXCEPTION(constructor->getReturnParameterList()->createTypeError(
|
BOOST_THROW_EXCEPTION(constructor->getReturnParameterList()->createTypeError(
|
||||||
"Non-empty \"returns\" directive for constructor."));
|
"Non-empty \"returns\" directive for constructor."));
|
||||||
|
|
||||||
|
FunctionDefinition const* fallbackFunction = getFallbackFunction();
|
||||||
|
if (fallbackFunction && fallbackFunction->getScope() == this && !fallbackFunction->getParameters().empty())
|
||||||
|
BOOST_THROW_EXCEPTION(fallbackFunction->getParameterList().createTypeError(
|
||||||
|
"Fallback function cannot take parameters."));
|
||||||
|
|
||||||
for (ASTPointer<ModifierDefinition> const& modifier: getFunctionModifiers())
|
for (ASTPointer<ModifierDefinition> const& modifier: getFunctionModifiers())
|
||||||
modifier->checkTypeRequirements();
|
modifier->checkTypeRequirements();
|
||||||
|
|
||||||
@ -99,6 +104,15 @@ FunctionDefinition const* ContractDefinition::getConstructor() const
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FunctionDefinition const* ContractDefinition::getFallbackFunction() const
|
||||||
|
{
|
||||||
|
for (ContractDefinition const* contract: getLinearizedBaseContracts())
|
||||||
|
for (ASTPointer<FunctionDefinition> const& f: contract->getDefinedFunctions())
|
||||||
|
if (f->getName().empty())
|
||||||
|
return f.get();
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
void ContractDefinition::checkIllegalOverrides() const
|
void ContractDefinition::checkIllegalOverrides() const
|
||||||
{
|
{
|
||||||
// TODO unify this at a later point. for this we need to put the constness and the access specifier
|
// TODO unify this at a later point. for this we need to put the constness and the access specifier
|
||||||
@ -147,7 +161,7 @@ vector<pair<FixedHash<4>, FunctionTypePointer>> const& ContractDefinition::getIn
|
|||||||
for (ContractDefinition const* contract: getLinearizedBaseContracts())
|
for (ContractDefinition const* contract: getLinearizedBaseContracts())
|
||||||
{
|
{
|
||||||
for (ASTPointer<FunctionDefinition> const& f: contract->getDefinedFunctions())
|
for (ASTPointer<FunctionDefinition> const& f: contract->getDefinedFunctions())
|
||||||
if (f->isPublic() && !f->isConstructor() && functionsSeen.count(f->getName()) == 0)
|
if (f->isPublic() && !f->isConstructor() && !f->getName().empty() && functionsSeen.count(f->getName()) == 0)
|
||||||
{
|
{
|
||||||
functionsSeen.insert(f->getName());
|
functionsSeen.insert(f->getName());
|
||||||
FixedHash<4> hash(dev::sha3(f->getCanonicalSignature()));
|
FixedHash<4> hash(dev::sha3(f->getCanonicalSignature()));
|
||||||
|
4
AST.h
4
AST.h
@ -235,8 +235,10 @@ public:
|
|||||||
std::vector<ContractDefinition const*> const& getLinearizedBaseContracts() const { return m_linearizedBaseContracts; }
|
std::vector<ContractDefinition const*> const& getLinearizedBaseContracts() const { return m_linearizedBaseContracts; }
|
||||||
void setLinearizedBaseContracts(std::vector<ContractDefinition const*> const& _bases) { m_linearizedBaseContracts = _bases; }
|
void setLinearizedBaseContracts(std::vector<ContractDefinition const*> const& _bases) { m_linearizedBaseContracts = _bases; }
|
||||||
|
|
||||||
/// Returns the constructor or nullptr if no constructor was specified
|
/// Returns the constructor or nullptr if no constructor was specified.
|
||||||
FunctionDefinition const* getConstructor() const;
|
FunctionDefinition const* getConstructor() const;
|
||||||
|
/// Returns the fallback function or nullptr if no constructor was specified.
|
||||||
|
FunctionDefinition const* getFallbackFunction() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void checkIllegalOverrides() const;
|
void checkIllegalOverrides() const;
|
||||||
|
10
Compiler.cpp
10
Compiler.cpp
@ -146,7 +146,7 @@ void Compiler::appendFunctionSelector(ContractDefinition const& _contract)
|
|||||||
map<FixedHash<4>, const eth::AssemblyItem> callDataUnpackerEntryPoints;
|
map<FixedHash<4>, const eth::AssemblyItem> callDataUnpackerEntryPoints;
|
||||||
|
|
||||||
// retrieve the function signature hash from the calldata
|
// retrieve the function signature hash from the calldata
|
||||||
m_context << u256(1) << u256(0);
|
if (!interfaceFunctions.empty())
|
||||||
CompilerUtils(m_context).loadFromMemory(0, 4, false, true);
|
CompilerUtils(m_context).loadFromMemory(0, 4, false, true);
|
||||||
|
|
||||||
// stack now is: 1 0 <funhash>
|
// stack now is: 1 0 <funhash>
|
||||||
@ -156,6 +156,14 @@ void Compiler::appendFunctionSelector(ContractDefinition const& _contract)
|
|||||||
m_context << eth::dupInstruction(1) << u256(FixedHash<4>::Arith(it.first)) << eth::Instruction::EQ;
|
m_context << eth::dupInstruction(1) << u256(FixedHash<4>::Arith(it.first)) << eth::Instruction::EQ;
|
||||||
m_context.appendConditionalJumpTo(callDataUnpackerEntryPoints.at(it.first));
|
m_context.appendConditionalJumpTo(callDataUnpackerEntryPoints.at(it.first));
|
||||||
}
|
}
|
||||||
|
if (FunctionDefinition const* fallback = _contract.getFallbackFunction())
|
||||||
|
{
|
||||||
|
eth::AssemblyItem returnTag = m_context.pushNewTag();
|
||||||
|
fallback->accept(*this);
|
||||||
|
m_context << returnTag;
|
||||||
|
appendReturnValuePacker(FunctionType(*fallback).getReturnParameterTypes());
|
||||||
|
}
|
||||||
|
else
|
||||||
m_context << eth::Instruction::STOP; // function not found
|
m_context << eth::Instruction::STOP; // function not found
|
||||||
|
|
||||||
for (auto const& it: interfaceFunctions)
|
for (auto const& it: interfaceFunctions)
|
||||||
|
@ -189,7 +189,11 @@ ASTPointer<FunctionDefinition> Parser::parseFunctionDefinition(bool _isPublic, A
|
|||||||
docstring = make_shared<ASTString>(m_scanner->getCurrentCommentLiteral());
|
docstring = make_shared<ASTString>(m_scanner->getCurrentCommentLiteral());
|
||||||
|
|
||||||
expectToken(Token::FUNCTION);
|
expectToken(Token::FUNCTION);
|
||||||
ASTPointer<ASTString> name(expectIdentifierToken());
|
ASTPointer<ASTString> name;
|
||||||
|
if (m_scanner->getCurrentToken() == Token::LPAREN)
|
||||||
|
name = make_shared<ASTString>(); // anonymous function
|
||||||
|
else
|
||||||
|
name = expectIdentifierToken();
|
||||||
ASTPointer<ParameterList> parameters(parseParameterList());
|
ASTPointer<ParameterList> parameters(parseParameterList());
|
||||||
bool isDeclaredConst = false;
|
bool isDeclaredConst = false;
|
||||||
vector<ASTPointer<ModifierInvocation>> modifiers;
|
vector<ASTPointer<ModifierInvocation>> modifiers;
|
||||||
|
@ -494,7 +494,7 @@ MemberList const& ContractType::getMembers() const
|
|||||||
{
|
{
|
||||||
for (ContractDefinition const* base: m_contract.getLinearizedBaseContracts())
|
for (ContractDefinition const* base: m_contract.getLinearizedBaseContracts())
|
||||||
for (ASTPointer<FunctionDefinition> const& function: base->getDefinedFunctions())
|
for (ASTPointer<FunctionDefinition> const& function: base->getDefinedFunctions())
|
||||||
if (!function->isConstructor())
|
if (!function->isConstructor() && !function->getName().empty())
|
||||||
members.insert(make_pair(function->getName(), make_shared<FunctionType>(*function, true)));
|
members.insert(make_pair(function->getName(), make_shared<FunctionType>(*function, true)));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -808,7 +808,7 @@ MemberList const& TypeType::getMembers() const
|
|||||||
// We are accessing the type of a base contract, so add all public and private
|
// We are accessing the type of a base contract, so add all public and private
|
||||||
// functions. Note that this does not add inherited functions on purpose.
|
// functions. Note that this does not add inherited functions on purpose.
|
||||||
for (ASTPointer<FunctionDefinition> const& f: contract.getDefinedFunctions())
|
for (ASTPointer<FunctionDefinition> const& f: contract.getDefinedFunctions())
|
||||||
if (!f->isConstructor())
|
if (!f->isConstructor() && !f->getName().empty())
|
||||||
members[f->getName()] = make_shared<FunctionType>(*f);
|
members[f->getName()] = make_shared<FunctionType>(*f);
|
||||||
}
|
}
|
||||||
m_members.reset(new MemberList(members));
|
m_members.reset(new MemberList(members));
|
||||||
|
Loading…
Reference in New Issue
Block a user