mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Optimize pattern matcher.
This commit is contained in:
parent
afad40ac5a
commit
652d8dab19
@ -185,7 +185,7 @@ class Rules: public boost::noncopyable
|
|||||||
public:
|
public:
|
||||||
Rules();
|
Rules();
|
||||||
void resetMatchGroups() { m_matchGroups.clear(); }
|
void resetMatchGroups() { m_matchGroups.clear(); }
|
||||||
vector<pair<Pattern, function<Pattern()>>> rules() const { return m_rules; }
|
vector<pair<Pattern, function<Pattern()>>> const& rules() const { return m_rules; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
using Expression = ExpressionClasses::Expression;
|
using Expression = ExpressionClasses::Expression;
|
||||||
@ -417,8 +417,7 @@ ExpressionClasses::Id ExpressionClasses::rebuildExpression(ExpressionTemplate co
|
|||||||
|
|
||||||
Pattern::Pattern(Instruction _instruction, std::vector<Pattern> const& _arguments):
|
Pattern::Pattern(Instruction _instruction, std::vector<Pattern> const& _arguments):
|
||||||
m_type(Operation),
|
m_type(Operation),
|
||||||
m_requireDataMatch(true),
|
m_instruction(_instruction),
|
||||||
m_data(_instruction),
|
|
||||||
m_arguments(_arguments)
|
m_arguments(_arguments)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@ -449,7 +448,10 @@ bool Pattern::matches(Expression const& _expr, ExpressionClasses const& _classes
|
|||||||
|
|
||||||
AssemblyItem Pattern::toAssemblyItem(SourceLocation const& _location) const
|
AssemblyItem Pattern::toAssemblyItem(SourceLocation const& _location) const
|
||||||
{
|
{
|
||||||
return AssemblyItem(m_type, m_data, _location);
|
if (m_type == Operation)
|
||||||
|
return AssemblyItem(m_instruction, _location);
|
||||||
|
else
|
||||||
|
return AssemblyItem(m_type, data(), _location);
|
||||||
}
|
}
|
||||||
|
|
||||||
string Pattern::toString() const
|
string Pattern::toString() const
|
||||||
@ -458,16 +460,16 @@ string Pattern::toString() const
|
|||||||
switch (m_type)
|
switch (m_type)
|
||||||
{
|
{
|
||||||
case Operation:
|
case Operation:
|
||||||
s << instructionInfo(Instruction(unsigned(m_data))).name;
|
s << instructionInfo(m_instruction).name;
|
||||||
break;
|
break;
|
||||||
case Push:
|
case Push:
|
||||||
s << "PUSH " << hex << m_data;
|
s << "PUSH " << hex << data();
|
||||||
break;
|
break;
|
||||||
case UndefinedItem:
|
case UndefinedItem:
|
||||||
s << "ANY";
|
s << "ANY";
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
s << "t=" << dec << m_type << " d=" << hex << m_data;
|
s << "t=" << dec << m_type << " d=" << hex << data();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (!m_requireDataMatch)
|
if (!m_requireDataMatch)
|
||||||
@ -489,13 +491,10 @@ bool Pattern::matchesBaseItem(AssemblyItem const* _item) const
|
|||||||
return false;
|
return false;
|
||||||
if (m_type != _item->type())
|
if (m_type != _item->type())
|
||||||
return false;
|
return false;
|
||||||
if (m_requireDataMatch)
|
else if (m_type == Operation)
|
||||||
{
|
return m_instruction == _item->instruction();
|
||||||
if (m_type == Operation)
|
else if (m_requireDataMatch)
|
||||||
return m_data == u256(byte(_item->instruction()));
|
return data() == _item->data();
|
||||||
else
|
|
||||||
return m_data == _item->data();
|
|
||||||
}
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -507,6 +506,11 @@ Pattern::Expression const& Pattern::matchGroupValue() const
|
|||||||
return *(*m_matchGroups)[m_matchGroup];
|
return *(*m_matchGroups)[m_matchGroup];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
u256 const& Pattern::data() const
|
||||||
|
{
|
||||||
|
assertThrow(m_data, OptimizerException, "");
|
||||||
|
return *m_data;
|
||||||
|
}
|
||||||
|
|
||||||
ExpressionTemplate::ExpressionTemplate(Pattern const& _pattern, SourceLocation const& _location)
|
ExpressionTemplate::ExpressionTemplate(Pattern const& _pattern, SourceLocation const& _location)
|
||||||
{
|
{
|
||||||
|
@ -135,7 +135,7 @@ public:
|
|||||||
// Matches a specific constant value.
|
// Matches a specific constant value.
|
||||||
Pattern(unsigned _value): Pattern(u256(_value)) {}
|
Pattern(unsigned _value): Pattern(u256(_value)) {}
|
||||||
// Matches a specific constant value.
|
// Matches a specific constant value.
|
||||||
Pattern(u256 const& _value): m_type(Push), m_requireDataMatch(true), m_data(_value) {}
|
Pattern(u256 const& _value): m_type(Push), m_requireDataMatch(true), m_data(std::make_shared<u256>(_value)) {}
|
||||||
// Matches a specific assembly item type or anything if not given.
|
// Matches a specific assembly item type or anything if not given.
|
||||||
Pattern(AssemblyItemType _type = UndefinedItem): m_type(_type) {}
|
Pattern(AssemblyItemType _type = UndefinedItem): m_type(_type) {}
|
||||||
// Matches a given instruction with given arguments
|
// Matches a given instruction with given arguments
|
||||||
@ -160,10 +160,12 @@ public:
|
|||||||
private:
|
private:
|
||||||
bool matchesBaseItem(AssemblyItem const* _item) const;
|
bool matchesBaseItem(AssemblyItem const* _item) const;
|
||||||
Expression const& matchGroupValue() const;
|
Expression const& matchGroupValue() const;
|
||||||
|
u256 const& data() const;
|
||||||
|
|
||||||
AssemblyItemType m_type;
|
AssemblyItemType m_type;
|
||||||
bool m_requireDataMatch = false;
|
bool m_requireDataMatch = false;
|
||||||
u256 m_data = 0;
|
Instruction m_instruction; ///< Only valid if m_type is Operation
|
||||||
|
std::shared_ptr<u256> m_data; ///< Only valid if m_type is not Operation
|
||||||
std::vector<Pattern> m_arguments;
|
std::vector<Pattern> m_arguments;
|
||||||
unsigned m_matchGroup = 0;
|
unsigned m_matchGroup = 0;
|
||||||
std::map<unsigned, Expression const*>* m_matchGroups = nullptr;
|
std::map<unsigned, Expression const*>* m_matchGroups = nullptr;
|
||||||
|
Loading…
Reference in New Issue
Block a user