aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorchriseth <c@ethdev.com>2015-03-13 20:14:51 +0800
committerchriseth <c@ethdev.com>2015-03-14 00:31:56 +0800
commita16677dcfbd7fd7d42fbd6166e234b1b7001ec59 (patch)
tree2a885476ca571246df3615f4fcd79e3c74353879
parent039b133c180b15863ee3104637c97822d815d932 (diff)
downloaddexon-solidity-a16677dcfbd7fd7d42fbd6166e234b1b7001ec59.tar.gz
dexon-solidity-a16677dcfbd7fd7d42fbd6166e234b1b7001ec59.tar.zst
dexon-solidity-a16677dcfbd7fd7d42fbd6166e234b1b7001ec59.zip
Fix gas for builtin.
Fixes #1300
-rw-r--r--ArrayUtils.cpp1
-rw-r--r--Compiler.cpp2
-rw-r--r--CompilerUtils.cpp4
-rw-r--r--ExpressionCompiler.cpp6
-rw-r--r--LValue.cpp1
5 files changed, 12 insertions, 2 deletions
diff --git a/ArrayUtils.cpp b/ArrayUtils.cpp
index f0d7d6a8..a064b2f5 100644
--- a/ArrayUtils.cpp
+++ b/ArrayUtils.cpp
@@ -125,6 +125,7 @@ void ArrayUtils::copyArrayToStorage(ArrayType const& _targetType, ArrayType cons
CompilerUtils(m_context).loadFromMemoryDynamic(*sourceBaseType, true, true, false);
else
solAssert(false, "Copying of unknown type requested: " + sourceBaseType->toString());
+ solAssert(2 + sourceBaseType->getSizeOnStack() <= 16, "Stack too deep.");
m_context << eth::dupInstruction(2 + sourceBaseType->getSizeOnStack());
StorageItem(m_context, *targetBaseType).storeValue(*sourceBaseType, SourceLocation(), true);
}
diff --git a/Compiler.cpp b/Compiler.cpp
index dc6e2c5a..b8ca03d3 100644
--- a/Compiler.cpp
+++ b/Compiler.cpp
@@ -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
unsigned stackDepth = m_context.getStackHeight() - stackHeightOfPreviousDynamicArgument;
+ solAssert(stackDepth <= 16, "Stack too deep.");
m_context << eth::dupInstruction(stackDepth) << eth::dupInstruction(stackDepth);
ArrayUtils(m_context).convertLengthToSize(*previousDynamicType, true);
m_context << eth::Instruction::ADD;
@@ -359,6 +360,7 @@ bool Compiler::visit(FunctionDefinition const& _function)
stackLayout.push_back(i);
stackLayout += vector<int>(c_localVariablesSize, -1);
+ solAssert(stackLayout.size() <= 17, "Stack too deep.");
while (stackLayout.back() != int(stackLayout.size() - 1))
if (stackLayout.back() < 0)
{
diff --git a/CompilerUtils.cpp b/CompilerUtils.cpp
index 7b078e03..e517e384 100644
--- a/CompilerUtils.cpp
+++ b/CompilerUtils.cpp
@@ -138,6 +138,7 @@ void CompilerUtils::moveToStackVariable(VariableDeclaration const& _variable)
{
unsigned const stackPosition = m_context.baseToCurrentStackOffset(m_context.getBaseStackOffsetOfVariable(_variable));
unsigned const size = _variable.getType()->getSizeOnStack();
+ solAssert(stackPosition >= size, "Variable size and position mismatch.");
// move variable starting from its top end in the stack
if (stackPosition - size + 1 > 16)
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)
{
- if (_stackDepth > 16)
- BOOST_THROW_EXCEPTION(CompilerError() << errinfo_comment("Stack too deep."));
+ solAssert(_stackDepth <= 16, "Stack too deep.");
for (unsigned i = 0; i < _itemSize; ++i)
m_context << eth::dupInstruction(_stackDepth);
}
diff --git a/ExpressionCompiler.cpp b/ExpressionCompiler.cpp
index 3cee40df..331979c7 100644
--- a/ExpressionCompiler.cpp
+++ b/ExpressionCompiler.cpp
@@ -233,9 +233,12 @@ bool ExpressionCompiler::visit(Assignment const& _assignment)
m_currentLValue->retrieveValue(_assignment.getLocation(), true);
appendOrdinaryBinaryOperatorCode(Token::AssignmentToBinaryOp(op), *_assignment.getType());
if (lvalueSize > 0)
+ {
+ solAssert(itemSize + lvalueSize <= 16, "Stack too deep.");
// value [lvalue_ref] updated_value
for (unsigned i = 0; i < itemSize; ++i)
m_context << eth::swapInstruction(itemSize + lvalueSize) << eth::Instruction::POP;
+ }
}
m_currentLValue->storeValue(*_assignment.getRightHandSide().getType(), _assignment.getLocation());
m_currentLValue.reset();
@@ -557,10 +560,13 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall)
case Location::SHA256:
case Location::RIPEMD160:
{
+ _functionCall.getExpression().accept(*this);
static const map<Location, u256> contractAddresses{{Location::ECRecover, 1},
{Location::SHA256, 2},
{Location::RIPEMD160, 3}};
m_context << contractAddresses.find(function.getLocation())->second;
+ for (unsigned i = function.getSizeOnStack(); i > 0; --i)
+ m_context << eth::swapInstruction(i);
appendExternalFunctionCall(function, arguments, true);
break;
}
diff --git a/LValue.cpp b/LValue.cpp
index a56ed54c..68d6797e 100644
--- a/LValue.cpp
+++ b/LValue.cpp
@@ -167,6 +167,7 @@ void StorageItem::storeValue(Type const& _sourceType, SourceLocation const& _loc
// stack: source_ref target_ref member_offset source_member_ref
StorageItem(m_context, *memberType).retrieveValue(_location, true);
// stack: source_ref target_ref member_offset source_value...
+ solAssert(2 + memberType->getSizeOnStack() <= 16, "Stack too deep.");
m_context << eth::dupInstruction(2 + memberType->getSizeOnStack())
<< eth::dupInstruction(2 + memberType->getSizeOnStack()) << eth::Instruction::ADD;
// stack: source_ref target_ref member_offset source_value... target_member_ref