mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
parent
b51ef4a357
commit
c2a9419e49
@ -168,7 +168,10 @@ void ArrayUtils::copyArrayToStorage(ArrayType const& _targetType, ArrayType cons
|
|||||||
else
|
else
|
||||||
solAssert(false, "Copying of unknown type requested: " + sourceBaseType->toString());
|
solAssert(false, "Copying of unknown type requested: " + sourceBaseType->toString());
|
||||||
// stack: target_ref target_data_end source_data_pos target_data_pos source_data_end [target_byte_offset] [source_byte_offset] <source_value>...
|
// stack: target_ref target_data_end source_data_pos target_data_pos source_data_end [target_byte_offset] [source_byte_offset] <source_value>...
|
||||||
solAssert(2 + byteOffsetSize + sourceBaseType->getSizeOnStack() <= 16, "Stack too deep.");
|
solAssert(
|
||||||
|
2 + byteOffsetSize + sourceBaseType->getSizeOnStack() <= 16,
|
||||||
|
"Stack too deep, try removing local variables."
|
||||||
|
);
|
||||||
// fetch target storage reference
|
// fetch target storage reference
|
||||||
m_context << eth::dupInstruction(2 + byteOffsetSize + sourceBaseType->getSizeOnStack());
|
m_context << eth::dupInstruction(2 + byteOffsetSize + sourceBaseType->getSizeOnStack());
|
||||||
if (haveByteOffsetTarget)
|
if (haveByteOffsetTarget)
|
||||||
|
@ -367,7 +367,7 @@ bool Compiler::visit(FunctionDefinition const& _function)
|
|||||||
stackLayout.push_back(i);
|
stackLayout.push_back(i);
|
||||||
stackLayout += vector<int>(c_localVariablesSize, -1);
|
stackLayout += vector<int>(c_localVariablesSize, -1);
|
||||||
|
|
||||||
solAssert(stackLayout.size() <= 17, "Stack too deep.");
|
solAssert(stackLayout.size() <= 17, "Stack too deep, try removing local variables.");
|
||||||
while (stackLayout.back() != int(stackLayout.size() - 1))
|
while (stackLayout.back() != int(stackLayout.size() - 1))
|
||||||
if (stackLayout.back() < 0)
|
if (stackLayout.back() < 0)
|
||||||
{
|
{
|
||||||
|
@ -142,22 +142,25 @@ void CompilerUtils::moveToStackVariable(VariableDeclaration const& _variable)
|
|||||||
solAssert(stackPosition >= size, "Variable size and position mismatch.");
|
solAssert(stackPosition >= size, "Variable size and position mismatch.");
|
||||||
// move variable starting from its top end in the stack
|
// move variable starting from its top end in the stack
|
||||||
if (stackPosition - size + 1 > 16)
|
if (stackPosition - size + 1 > 16)
|
||||||
BOOST_THROW_EXCEPTION(CompilerError() << errinfo_sourceLocation(_variable.getLocation())
|
BOOST_THROW_EXCEPTION(
|
||||||
<< errinfo_comment("Stack too deep."));
|
CompilerError() <<
|
||||||
|
errinfo_sourceLocation(_variable.getLocation()) <<
|
||||||
|
errinfo_comment("Stack too deep, try removing local variables.")
|
||||||
|
);
|
||||||
for (unsigned i = 0; i < size; ++i)
|
for (unsigned i = 0; i < size; ++i)
|
||||||
m_context << eth::swapInstruction(stackPosition - size + 1) << eth::Instruction::POP;
|
m_context << eth::swapInstruction(stackPosition - size + 1) << eth::Instruction::POP;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CompilerUtils::copyToStackTop(unsigned _stackDepth, unsigned _itemSize)
|
void CompilerUtils::copyToStackTop(unsigned _stackDepth, unsigned _itemSize)
|
||||||
{
|
{
|
||||||
solAssert(_stackDepth <= 16, "Stack too deep.");
|
solAssert(_stackDepth <= 16, "Stack too deep, try removing local variables.");
|
||||||
for (unsigned i = 0; i < _itemSize; ++i)
|
for (unsigned i = 0; i < _itemSize; ++i)
|
||||||
m_context << eth::dupInstruction(_stackDepth);
|
m_context << eth::dupInstruction(_stackDepth);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CompilerUtils::moveToStackTop(unsigned _stackDepth)
|
void CompilerUtils::moveToStackTop(unsigned _stackDepth)
|
||||||
{
|
{
|
||||||
solAssert(_stackDepth <= 15, "Stack too deep.");
|
solAssert(_stackDepth <= 15, "Stack too deep, try removing local variables.");
|
||||||
for (unsigned i = 0; i < _stackDepth; ++i)
|
for (unsigned i = 0; i < _stackDepth; ++i)
|
||||||
m_context << eth::swapInstruction(1 + i);
|
m_context << eth::swapInstruction(1 + i);
|
||||||
}
|
}
|
||||||
|
@ -263,7 +263,7 @@ bool ExpressionCompiler::visit(Assignment const& _assignment)
|
|||||||
appendOrdinaryBinaryOperatorCode(Token::AssignmentToBinaryOp(op), *_assignment.getType());
|
appendOrdinaryBinaryOperatorCode(Token::AssignmentToBinaryOp(op), *_assignment.getType());
|
||||||
if (lvalueSize > 0)
|
if (lvalueSize > 0)
|
||||||
{
|
{
|
||||||
solAssert(itemSize + lvalueSize <= 16, "Stack too deep.");
|
solAssert(itemSize + lvalueSize <= 16, "Stack too deep, try removing local variables.");
|
||||||
// value [lvalue_ref] updated_value
|
// value [lvalue_ref] updated_value
|
||||||
for (unsigned i = 0; i < itemSize; ++i)
|
for (unsigned i = 0; i < itemSize; ++i)
|
||||||
m_context << eth::swapInstruction(itemSize + lvalueSize) << eth::Instruction::POP;
|
m_context << eth::swapInstruction(itemSize + lvalueSize) << eth::Instruction::POP;
|
||||||
|
26
LValue.cpp
26
LValue.cpp
@ -42,8 +42,11 @@ void StackVariable::retrieveValue(SourceLocation const& _location, bool) const
|
|||||||
{
|
{
|
||||||
unsigned stackPos = m_context.baseToCurrentStackOffset(m_baseStackOffset);
|
unsigned stackPos = m_context.baseToCurrentStackOffset(m_baseStackOffset);
|
||||||
if (stackPos >= 15) //@todo correct this by fetching earlier or moving to memory
|
if (stackPos >= 15) //@todo correct this by fetching earlier or moving to memory
|
||||||
BOOST_THROW_EXCEPTION(CompilerError()
|
BOOST_THROW_EXCEPTION(
|
||||||
<< errinfo_sourceLocation(_location) << errinfo_comment("Stack too deep."));
|
CompilerError() <<
|
||||||
|
errinfo_sourceLocation(_location) <<
|
||||||
|
errinfo_comment("Stack too deep, try removing local variables.")
|
||||||
|
);
|
||||||
for (unsigned i = 0; i < m_size; ++i)
|
for (unsigned i = 0; i < m_size; ++i)
|
||||||
m_context << eth::dupInstruction(stackPos + 1);
|
m_context << eth::dupInstruction(stackPos + 1);
|
||||||
}
|
}
|
||||||
@ -52,8 +55,11 @@ void StackVariable::storeValue(Type const&, SourceLocation const& _location, boo
|
|||||||
{
|
{
|
||||||
unsigned stackDiff = m_context.baseToCurrentStackOffset(m_baseStackOffset) - m_size + 1;
|
unsigned stackDiff = m_context.baseToCurrentStackOffset(m_baseStackOffset) - m_size + 1;
|
||||||
if (stackDiff > 16)
|
if (stackDiff > 16)
|
||||||
BOOST_THROW_EXCEPTION(CompilerError()
|
BOOST_THROW_EXCEPTION(
|
||||||
<< errinfo_sourceLocation(_location) << errinfo_comment("Stack too deep."));
|
CompilerError() <<
|
||||||
|
errinfo_sourceLocation(_location) <<
|
||||||
|
errinfo_comment("Stack too deep, try removing local variables.")
|
||||||
|
);
|
||||||
else if (stackDiff > 0)
|
else if (stackDiff > 0)
|
||||||
for (unsigned i = 0; i < m_size; ++i)
|
for (unsigned i = 0; i < m_size; ++i)
|
||||||
m_context << eth::swapInstruction(stackDiff) << eth::Instruction::POP;
|
m_context << eth::swapInstruction(stackDiff) << eth::Instruction::POP;
|
||||||
@ -65,8 +71,11 @@ void StackVariable::setToZero(SourceLocation const& _location, bool) const
|
|||||||
{
|
{
|
||||||
unsigned stackDiff = m_context.baseToCurrentStackOffset(m_baseStackOffset);
|
unsigned stackDiff = m_context.baseToCurrentStackOffset(m_baseStackOffset);
|
||||||
if (stackDiff > 16)
|
if (stackDiff > 16)
|
||||||
BOOST_THROW_EXCEPTION(CompilerError()
|
BOOST_THROW_EXCEPTION(
|
||||||
<< errinfo_sourceLocation(_location) << errinfo_comment("Stack too deep."));
|
CompilerError() <<
|
||||||
|
errinfo_sourceLocation(_location) <<
|
||||||
|
errinfo_comment("Stack too deep, try removing local variables.")
|
||||||
|
);
|
||||||
solAssert(stackDiff >= m_size - 1, "");
|
solAssert(stackDiff >= m_size - 1, "");
|
||||||
for (unsigned i = 0; i < m_size; ++i)
|
for (unsigned i = 0; i < m_size; ++i)
|
||||||
m_context << u256(0) << eth::swapInstruction(stackDiff + 1 - i)
|
m_context << u256(0) << eth::swapInstruction(stackDiff + 1 - i)
|
||||||
@ -204,7 +213,10 @@ void StorageItem::storeValue(Type const& _sourceType, SourceLocation const& _loc
|
|||||||
// stack: source_ref source_off target_ref target_off member_slot_offset member_byte_offset source_member_ref source_member_off
|
// stack: source_ref source_off target_ref target_off member_slot_offset member_byte_offset source_member_ref source_member_off
|
||||||
StorageItem(m_context, *memberType).retrieveValue(_location, true);
|
StorageItem(m_context, *memberType).retrieveValue(_location, true);
|
||||||
// stack: source_ref source_off target_ref target_off member_offset source_value...
|
// stack: source_ref source_off target_ref target_off member_offset source_value...
|
||||||
solAssert(4 + memberType->getSizeOnStack() <= 16, "Stack too deep.");
|
solAssert(
|
||||||
|
4 + memberType->getSizeOnStack() <= 16,
|
||||||
|
"Stack too deep, try removing local varibales."
|
||||||
|
);
|
||||||
m_context
|
m_context
|
||||||
<< eth::dupInstruction(4 + memberType->getSizeOnStack())
|
<< eth::dupInstruction(4 + memberType->getSizeOnStack())
|
||||||
<< eth::dupInstruction(3 + memberType->getSizeOnStack()) << eth::Instruction::ADD
|
<< eth::dupInstruction(3 + memberType->getSizeOnStack()) << eth::Instruction::ADD
|
||||||
|
Loading…
Reference in New Issue
Block a user