mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Add recomputation check for number representation.
This commit is contained in:
parent
2c1fb46bc3
commit
54210ea89f
@ -232,6 +232,54 @@ AssemblyItems ComputeMethod::findRepresentation(u256 const& _value)
|
||||
}
|
||||
}
|
||||
|
||||
bool ComputeMethod::checkRepresentation(u256 const& _value)
|
||||
{
|
||||
// This is a tiny EVM that can only evaluate some instructions.
|
||||
vector<u256> stack;
|
||||
for (AssemblyItem const& item: m_routine)
|
||||
{
|
||||
switch (item.type())
|
||||
{
|
||||
case Operation:
|
||||
{
|
||||
if (stack.size() < size_t(item.arguments()))
|
||||
return false;
|
||||
u256* sp = &stack.back();
|
||||
switch (item.instruction())
|
||||
{
|
||||
case Instruction::MUL:
|
||||
sp[-1] = sp[0] * sp[-1];
|
||||
break;
|
||||
case Instruction::EXP:
|
||||
if (sp[-1] > 0xff)
|
||||
return false;
|
||||
sp[-1] = boost::multiprecision::pow(sp[0], unsigned(sp[-1]));
|
||||
break;
|
||||
case Instruction::ADD:
|
||||
sp[-1] = sp[0] + sp[-1];
|
||||
break;
|
||||
case Instruction::SUB:
|
||||
sp[-1] = sp[0] - sp[-1];
|
||||
break;
|
||||
case Instruction::NOT:
|
||||
sp[0] = ~sp[0];
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
stack.resize(stack.size() + item.deposit());
|
||||
break;
|
||||
}
|
||||
case Push:
|
||||
stack.push_back(item.data());
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return stack.size() == 1 && stack.front() == _value;
|
||||
}
|
||||
|
||||
bigint ComputeMethod::gasNeeded(AssemblyItems const& _routine)
|
||||
{
|
||||
size_t numExps = count(_routine.begin(), _routine.end(), Instruction::EXP);
|
||||
|
@ -21,10 +21,13 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include <libevmasm/Exceptions.h>
|
||||
|
||||
#include <libdevcore/CommonData.h>
|
||||
#include <libdevcore/CommonIO.h>
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace dev
|
||||
{
|
||||
namespace eth
|
||||
@ -130,6 +133,8 @@ public:
|
||||
ConstantOptimisationMethod(_params, _value)
|
||||
{
|
||||
m_routine = findRepresentation(m_value);
|
||||
if (!checkRepresentation(m_value))
|
||||
BOOST_THROW_EXCEPTION(AssemblyException());
|
||||
}
|
||||
|
||||
virtual bigint gasNeeded() override { return gasNeeded(m_routine); }
|
||||
@ -141,6 +146,8 @@ public:
|
||||
protected:
|
||||
/// Tries to recursively find a way to compute @a _value.
|
||||
AssemblyItems findRepresentation(u256 const& _value);
|
||||
/// Recomputes the value from the calculated representation and checks for correctness.
|
||||
bool checkRepresentation(u256 const& _value);
|
||||
bigint gasNeeded(AssemblyItems const& _routine);
|
||||
|
||||
/// Counter for the complexity of optimization, will stop when it reaches zero.
|
||||
|
Loading…
Reference in New Issue
Block a user