mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Add appendCallValueCheck
This commit is contained in:
parent
a35ca910c7
commit
910269a29f
@ -102,6 +102,13 @@ void ContractCompiler::initializeContext(
|
|||||||
m_context.resetVisitedNodes(&_contract);
|
m_context.resetVisitedNodes(&_contract);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ContractCompiler::appendCallValueCheck()
|
||||||
|
{
|
||||||
|
// Throw if function is not payable but call contained ether.
|
||||||
|
m_context << Instruction::CALLVALUE;
|
||||||
|
m_context.appendConditionalJumpTo(m_context.errorTag());
|
||||||
|
}
|
||||||
|
|
||||||
void ContractCompiler::appendInitAndConstructorCode(ContractDefinition const& _contract)
|
void ContractCompiler::appendInitAndConstructorCode(ContractDefinition const& _contract)
|
||||||
{
|
{
|
||||||
// Determine the arguments that are used for the base constructors.
|
// Determine the arguments that are used for the base constructors.
|
||||||
@ -138,11 +145,7 @@ void ContractCompiler::appendInitAndConstructorCode(ContractDefinition const& _c
|
|||||||
else if (auto c = m_context.nextConstructor(_contract))
|
else if (auto c = m_context.nextConstructor(_contract))
|
||||||
appendBaseConstructor(*c);
|
appendBaseConstructor(*c);
|
||||||
else
|
else
|
||||||
{
|
appendCallValueCheck();
|
||||||
// Throw if function is not payable but call contained ether.
|
|
||||||
m_context << Instruction::CALLVALUE;
|
|
||||||
m_context.appendConditionalJumpTo(m_context.errorTag());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t ContractCompiler::packIntoContractCreator(ContractDefinition const& _contract)
|
size_t ContractCompiler::packIntoContractCreator(ContractDefinition const& _contract)
|
||||||
@ -191,11 +194,8 @@ void ContractCompiler::appendConstructor(FunctionDefinition const& _constructor)
|
|||||||
{
|
{
|
||||||
CompilerContext::LocationSetter locationSetter(m_context, _constructor);
|
CompilerContext::LocationSetter locationSetter(m_context, _constructor);
|
||||||
if (!_constructor.isPayable())
|
if (!_constructor.isPayable())
|
||||||
{
|
appendCallValueCheck();
|
||||||
// Throw if function is not payable but call contained ether.
|
|
||||||
m_context << Instruction::CALLVALUE;
|
|
||||||
m_context.appendConditionalJumpTo(m_context.errorTag());
|
|
||||||
}
|
|
||||||
// copy constructor arguments from code to memory and then to stack, they are supplied after the actual program
|
// copy constructor arguments from code to memory and then to stack, they are supplied after the actual program
|
||||||
if (!_constructor.parameters().empty())
|
if (!_constructor.parameters().empty())
|
||||||
{
|
{
|
||||||
@ -263,11 +263,8 @@ void ContractCompiler::appendFunctionSelector(ContractDefinition const& _contrac
|
|||||||
if (fallback)
|
if (fallback)
|
||||||
{
|
{
|
||||||
if (!fallback->isPayable())
|
if (!fallback->isPayable())
|
||||||
{
|
appendCallValueCheck();
|
||||||
// Throw if function is not payable but call contained ether.
|
|
||||||
m_context << Instruction::CALLVALUE;
|
|
||||||
m_context.appendConditionalJumpTo(m_context.errorTag());
|
|
||||||
}
|
|
||||||
eth::AssemblyItem returnTag = m_context.pushNewTag();
|
eth::AssemblyItem returnTag = m_context.pushNewTag();
|
||||||
fallback->accept(*this);
|
fallback->accept(*this);
|
||||||
m_context << returnTag;
|
m_context << returnTag;
|
||||||
@ -286,11 +283,7 @@ void ContractCompiler::appendFunctionSelector(ContractDefinition const& _contrac
|
|||||||
// We have to allow this for libraries, because value of the previous
|
// We have to allow this for libraries, because value of the previous
|
||||||
// call is still visible in the delegatecall.
|
// call is still visible in the delegatecall.
|
||||||
if (!functionType->isPayable() && !_contract.isLibrary())
|
if (!functionType->isPayable() && !_contract.isLibrary())
|
||||||
{
|
appendCallValueCheck();
|
||||||
// Throw if function is not payable but call contained ether.
|
|
||||||
m_context << Instruction::CALLVALUE;
|
|
||||||
m_context.appendConditionalJumpTo(m_context.errorTag());
|
|
||||||
}
|
|
||||||
|
|
||||||
eth::AssemblyItem returnTag = m_context.pushNewTag();
|
eth::AssemblyItem returnTag = m_context.pushNewTag();
|
||||||
m_context << CompilerUtils::dataStartOffset;
|
m_context << CompilerUtils::dataStartOffset;
|
||||||
|
@ -80,6 +80,7 @@ private:
|
|||||||
void appendBaseConstructor(FunctionDefinition const& _constructor);
|
void appendBaseConstructor(FunctionDefinition const& _constructor);
|
||||||
void appendConstructor(FunctionDefinition const& _constructor);
|
void appendConstructor(FunctionDefinition const& _constructor);
|
||||||
void appendFunctionSelector(ContractDefinition const& _contract);
|
void appendFunctionSelector(ContractDefinition const& _contract);
|
||||||
|
void appendCallValueCheck();
|
||||||
/// Creates code that unpacks the arguments for the given function represented by a vector of TypePointers.
|
/// Creates code that unpacks the arguments for the given function represented by a vector of TypePointers.
|
||||||
/// From memory if @a _fromMemory is true, otherwise from call data.
|
/// From memory if @a _fromMemory is true, otherwise from call data.
|
||||||
/// Expects source offset on the stack, which is removed.
|
/// Expects source offset on the stack, which is removed.
|
||||||
|
Loading…
Reference in New Issue
Block a user