mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
parent
039b133c18
commit
a16677dcfb
@ -125,6 +125,7 @@ void ArrayUtils::copyArrayToStorage(ArrayType const& _targetType, ArrayType cons
|
|||||||
CompilerUtils(m_context).loadFromMemoryDynamic(*sourceBaseType, true, true, false);
|
CompilerUtils(m_context).loadFromMemoryDynamic(*sourceBaseType, true, true, false);
|
||||||
else
|
else
|
||||||
solAssert(false, "Copying of unknown type requested: " + sourceBaseType->toString());
|
solAssert(false, "Copying of unknown type requested: " + sourceBaseType->toString());
|
||||||
|
solAssert(2 + sourceBaseType->getSizeOnStack() <= 16, "Stack too deep.");
|
||||||
m_context << eth::dupInstruction(2 + sourceBaseType->getSizeOnStack());
|
m_context << eth::dupInstruction(2 + sourceBaseType->getSizeOnStack());
|
||||||
StorageItem(m_context, *targetBaseType).storeValue(*sourceBaseType, SourceLocation(), true);
|
StorageItem(m_context, *targetBaseType).storeValue(*sourceBaseType, SourceLocation(), true);
|
||||||
}
|
}
|
||||||
|
@ -228,6 +228,7 @@ void Compiler::appendCalldataUnpacker(TypePointers const& _typeParameters, bool
|
|||||||
{
|
{
|
||||||
// Retrieve data start offset by adding length to start offset of previous dynamic type
|
// Retrieve data start offset by adding length to start offset of previous dynamic type
|
||||||
unsigned stackDepth = m_context.getStackHeight() - stackHeightOfPreviousDynamicArgument;
|
unsigned stackDepth = m_context.getStackHeight() - stackHeightOfPreviousDynamicArgument;
|
||||||
|
solAssert(stackDepth <= 16, "Stack too deep.");
|
||||||
m_context << eth::dupInstruction(stackDepth) << eth::dupInstruction(stackDepth);
|
m_context << eth::dupInstruction(stackDepth) << eth::dupInstruction(stackDepth);
|
||||||
ArrayUtils(m_context).convertLengthToSize(*previousDynamicType, true);
|
ArrayUtils(m_context).convertLengthToSize(*previousDynamicType, true);
|
||||||
m_context << eth::Instruction::ADD;
|
m_context << eth::Instruction::ADD;
|
||||||
@ -359,6 +360,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.");
|
||||||
while (stackLayout.back() != int(stackLayout.size() - 1))
|
while (stackLayout.back() != int(stackLayout.size() - 1))
|
||||||
if (stackLayout.back() < 0)
|
if (stackLayout.back() < 0)
|
||||||
{
|
{
|
||||||
|
@ -138,6 +138,7 @@ void CompilerUtils::moveToStackVariable(VariableDeclaration const& _variable)
|
|||||||
{
|
{
|
||||||
unsigned const stackPosition = m_context.baseToCurrentStackOffset(m_context.getBaseStackOffsetOfVariable(_variable));
|
unsigned const stackPosition = m_context.baseToCurrentStackOffset(m_context.getBaseStackOffsetOfVariable(_variable));
|
||||||
unsigned const size = _variable.getType()->getSizeOnStack();
|
unsigned const size = _variable.getType()->getSizeOnStack();
|
||||||
|
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(CompilerError() << errinfo_sourceLocation(_variable.getLocation())
|
||||||
@ -148,8 +149,7 @@ void CompilerUtils::moveToStackVariable(VariableDeclaration const& _variable)
|
|||||||
|
|
||||||
void CompilerUtils::copyToStackTop(unsigned _stackDepth, unsigned _itemSize)
|
void CompilerUtils::copyToStackTop(unsigned _stackDepth, unsigned _itemSize)
|
||||||
{
|
{
|
||||||
if (_stackDepth > 16)
|
solAssert(_stackDepth <= 16, "Stack too deep.");
|
||||||
BOOST_THROW_EXCEPTION(CompilerError() << errinfo_comment("Stack too deep."));
|
|
||||||
for (unsigned i = 0; i < _itemSize; ++i)
|
for (unsigned i = 0; i < _itemSize; ++i)
|
||||||
m_context << eth::dupInstruction(_stackDepth);
|
m_context << eth::dupInstruction(_stackDepth);
|
||||||
}
|
}
|
||||||
|
@ -233,9 +233,12 @@ bool ExpressionCompiler::visit(Assignment const& _assignment)
|
|||||||
m_currentLValue->retrieveValue(_assignment.getLocation(), true);
|
m_currentLValue->retrieveValue(_assignment.getLocation(), true);
|
||||||
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.");
|
||||||
// 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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
m_currentLValue->storeValue(*_assignment.getRightHandSide().getType(), _assignment.getLocation());
|
m_currentLValue->storeValue(*_assignment.getRightHandSide().getType(), _assignment.getLocation());
|
||||||
m_currentLValue.reset();
|
m_currentLValue.reset();
|
||||||
@ -557,10 +560,13 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall)
|
|||||||
case Location::SHA256:
|
case Location::SHA256:
|
||||||
case Location::RIPEMD160:
|
case Location::RIPEMD160:
|
||||||
{
|
{
|
||||||
|
_functionCall.getExpression().accept(*this);
|
||||||
static const map<Location, u256> contractAddresses{{Location::ECRecover, 1},
|
static const map<Location, u256> contractAddresses{{Location::ECRecover, 1},
|
||||||
{Location::SHA256, 2},
|
{Location::SHA256, 2},
|
||||||
{Location::RIPEMD160, 3}};
|
{Location::RIPEMD160, 3}};
|
||||||
m_context << contractAddresses.find(function.getLocation())->second;
|
m_context << contractAddresses.find(function.getLocation())->second;
|
||||||
|
for (unsigned i = function.getSizeOnStack(); i > 0; --i)
|
||||||
|
m_context << eth::swapInstruction(i);
|
||||||
appendExternalFunctionCall(function, arguments, true);
|
appendExternalFunctionCall(function, arguments, true);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -167,6 +167,7 @@ void StorageItem::storeValue(Type const& _sourceType, SourceLocation const& _loc
|
|||||||
// stack: source_ref target_ref member_offset source_member_ref
|
// stack: source_ref target_ref member_offset source_member_ref
|
||||||
StorageItem(m_context, *memberType).retrieveValue(_location, true);
|
StorageItem(m_context, *memberType).retrieveValue(_location, true);
|
||||||
// stack: source_ref target_ref member_offset source_value...
|
// stack: source_ref target_ref member_offset source_value...
|
||||||
|
solAssert(2 + memberType->getSizeOnStack() <= 16, "Stack too deep.");
|
||||||
m_context << eth::dupInstruction(2 + memberType->getSizeOnStack())
|
m_context << eth::dupInstruction(2 + memberType->getSizeOnStack())
|
||||||
<< eth::dupInstruction(2 + memberType->getSizeOnStack()) << eth::Instruction::ADD;
|
<< eth::dupInstruction(2 + memberType->getSizeOnStack()) << eth::Instruction::ADD;
|
||||||
// stack: source_ref target_ref member_offset source_value... target_member_ref
|
// stack: source_ref target_ref member_offset source_value... target_member_ref
|
||||||
|
Loading…
Reference in New Issue
Block a user