mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Gas meter for Yul expressions.
This commit is contained in:
parent
0a98fd4c7c
commit
1fc11f46fc
@ -22,10 +22,13 @@
|
|||||||
|
|
||||||
#include <libyul/AsmData.h>
|
#include <libyul/AsmData.h>
|
||||||
#include <libyul/Exceptions.h>
|
#include <libyul/Exceptions.h>
|
||||||
|
#include <libyul/Utilities.h>
|
||||||
|
|
||||||
#include <libevmasm/Instruction.h>
|
#include <libevmasm/Instruction.h>
|
||||||
|
#include <libevmasm/GasMeter.h>
|
||||||
|
|
||||||
#include <libdevcore/Visitor.h>
|
#include <libdevcore/Visitor.h>
|
||||||
|
#include <libdevcore/CommonData.h>
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace dev;
|
using namespace dev;
|
||||||
@ -151,6 +154,54 @@ void CodeCost::visit(Expression const& _expression)
|
|||||||
ASTWalker::visit(_expression);
|
ASTWalker::visit(_expression);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pair<size_t, size_t> GasMeter::gasCosts(
|
||||||
|
Expression const& _expression,
|
||||||
|
langutil::EVMVersion _evmVersion,
|
||||||
|
bool _isCreation
|
||||||
|
)
|
||||||
|
{
|
||||||
|
GasMeter gm(_evmVersion, _isCreation);
|
||||||
|
gm.visit(_expression);
|
||||||
|
return {gm.m_runGas, gm.m_dataGas};
|
||||||
|
}
|
||||||
|
|
||||||
|
void GasMeter::operator()(FunctionCall const&)
|
||||||
|
{
|
||||||
|
yulAssert(false, "Functions not implemented.");
|
||||||
|
}
|
||||||
|
|
||||||
|
void GasMeter::operator()(FunctionalInstruction const& _fun)
|
||||||
|
{
|
||||||
|
ASTWalker::operator()(_fun);
|
||||||
|
if (_fun.instruction == eth::Instruction::EXP)
|
||||||
|
m_runGas += dev::eth::GasCosts::expGas + dev::eth::GasCosts::expByteGas(m_evmVersion);
|
||||||
|
else
|
||||||
|
m_runGas += dev::eth::GasMeter::runGas(_fun.instruction);
|
||||||
|
m_dataGas += singleByteDataGas();
|
||||||
|
}
|
||||||
|
|
||||||
|
void GasMeter::operator()(Literal const& _lit)
|
||||||
|
{
|
||||||
|
m_runGas += dev::eth::GasMeter::runGas(dev::eth::Instruction::PUSH1);
|
||||||
|
m_dataGas +=
|
||||||
|
singleByteDataGas() +
|
||||||
|
size_t(dev::eth::GasMeter::dataGas(dev::toCompactBigEndian(valueOfLiteral(_lit), 1), m_isCreation));
|
||||||
|
}
|
||||||
|
|
||||||
|
void GasMeter::operator()(Identifier const&)
|
||||||
|
{
|
||||||
|
m_runGas += dev::eth::GasMeter::runGas(dev::eth::Instruction::DUP1);
|
||||||
|
m_dataGas += singleByteDataGas();
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t GasMeter::singleByteDataGas() const
|
||||||
|
{
|
||||||
|
if (m_isCreation)
|
||||||
|
return dev::eth::GasCosts::txDataNonZeroGas;
|
||||||
|
else
|
||||||
|
return dev::eth::GasCosts::createDataGas;
|
||||||
|
}
|
||||||
|
|
||||||
void AssignmentCounter::operator()(Assignment const& _assignment)
|
void AssignmentCounter::operator()(Assignment const& _assignment)
|
||||||
{
|
{
|
||||||
for (auto const& variable: _assignment.variableNames)
|
for (auto const& variable: _assignment.variableNames)
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <libyul/optimiser/ASTWalker.h>
|
#include <libyul/optimiser/ASTWalker.h>
|
||||||
|
#include <liblangutil/EVMVersion.h>
|
||||||
|
|
||||||
namespace yul
|
namespace yul
|
||||||
{
|
{
|
||||||
@ -84,6 +85,42 @@ private:
|
|||||||
size_t m_cost = 0;
|
size_t m_cost = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gas meter for expressions only involving literals, identifiers and
|
||||||
|
* EVM instructions.
|
||||||
|
*
|
||||||
|
* Assumes that EXP is not used with exponents larger than a single byte.
|
||||||
|
*/
|
||||||
|
class GasMeter: public ASTWalker
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/// @returns the runtime costs and the data cost of
|
||||||
|
/// evaluating the given expression.
|
||||||
|
static std::pair<size_t, size_t> gasCosts(
|
||||||
|
Expression const& _expression,
|
||||||
|
langutil::EVMVersion _evmVersion,
|
||||||
|
bool _isCreation = false
|
||||||
|
);
|
||||||
|
|
||||||
|
private:
|
||||||
|
GasMeter(langutil::EVMVersion _evmVersion, bool _isCreation):
|
||||||
|
m_evmVersion(_evmVersion),
|
||||||
|
m_isCreation{_isCreation}
|
||||||
|
{}
|
||||||
|
|
||||||
|
void operator()(FunctionCall const& _funCall) override;
|
||||||
|
void operator()(FunctionalInstruction const& _instr) override;
|
||||||
|
void operator()(Literal const& _literal) override;
|
||||||
|
void operator()(Identifier const& _identifier) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
size_t singleByteDataGas() const;
|
||||||
|
|
||||||
|
langutil::EVMVersion m_evmVersion;
|
||||||
|
bool m_isCreation = false;
|
||||||
|
size_t m_runGas = 0;
|
||||||
|
size_t m_dataGas = 0;
|
||||||
|
};
|
||||||
/**
|
/**
|
||||||
* Counts the number of assignments to every variable.
|
* Counts the number of assignments to every variable.
|
||||||
* Only works after running the Disambiguator.
|
* Only works after running the Disambiguator.
|
||||||
|
Loading…
Reference in New Issue
Block a user