mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Prevent instructions to be generated as names.
This commit is contained in:
parent
eac0048176
commit
0af8d758a5
@ -53,6 +53,27 @@ shared_ptr<Block> Parser::parse(std::shared_ptr<Scanner> const& _scanner, bool _
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::map<string, dev::eth::Instruction> const& Parser::instructions()
|
||||||
|
{
|
||||||
|
// Allowed instructions, lowercase names.
|
||||||
|
static map<string, dev::eth::Instruction> s_instructions;
|
||||||
|
if (s_instructions.empty())
|
||||||
|
{
|
||||||
|
for (auto const& instruction: dev::eth::c_instructions)
|
||||||
|
{
|
||||||
|
if (
|
||||||
|
instruction.second == dev::eth::Instruction::JUMPDEST ||
|
||||||
|
dev::eth::isPushInstruction(instruction.second)
|
||||||
|
)
|
||||||
|
continue;
|
||||||
|
string name = instruction.first;
|
||||||
|
transform(name.begin(), name.end(), name.begin(), [](unsigned char _c) { return tolower(_c); });
|
||||||
|
s_instructions[name] = instruction.second;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return s_instructions;
|
||||||
|
}
|
||||||
|
|
||||||
Block Parser::parseBlock()
|
Block Parser::parseBlock()
|
||||||
{
|
{
|
||||||
RecursionGuard recursionGuard(*this);
|
RecursionGuard recursionGuard(*this);
|
||||||
@ -340,27 +361,6 @@ Expression Parser::parseExpression()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::map<string, dev::eth::Instruction> const& Parser::instructions()
|
|
||||||
{
|
|
||||||
// Allowed instructions, lowercase names.
|
|
||||||
static map<string, dev::eth::Instruction> s_instructions;
|
|
||||||
if (s_instructions.empty())
|
|
||||||
{
|
|
||||||
for (auto const& instruction: dev::eth::c_instructions)
|
|
||||||
{
|
|
||||||
if (
|
|
||||||
instruction.second == dev::eth::Instruction::JUMPDEST ||
|
|
||||||
dev::eth::isPushInstruction(instruction.second)
|
|
||||||
)
|
|
||||||
continue;
|
|
||||||
string name = instruction.first;
|
|
||||||
transform(name.begin(), name.end(), name.begin(), [](unsigned char _c) { return tolower(_c); });
|
|
||||||
s_instructions[name] = instruction.second;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return s_instructions;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::map<dev::eth::Instruction, string> const& Parser::instructionNames()
|
std::map<dev::eth::Instruction, string> const& Parser::instructionNames()
|
||||||
{
|
{
|
||||||
static map<dev::eth::Instruction, string> s_instructionNames;
|
static map<dev::eth::Instruction, string> s_instructionNames;
|
||||||
|
@ -46,6 +46,9 @@ public:
|
|||||||
/// @returns an empty shared pointer on error.
|
/// @returns an empty shared pointer on error.
|
||||||
std::shared_ptr<Block> parse(std::shared_ptr<langutil::Scanner> const& _scanner, bool _reuseScanner);
|
std::shared_ptr<Block> parse(std::shared_ptr<langutil::Scanner> const& _scanner, bool _reuseScanner);
|
||||||
|
|
||||||
|
/// @returns a map of all EVM instructions available to assembly.
|
||||||
|
static std::map<std::string, dev::eth::Instruction> const& instructions();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
using ElementaryOperation = boost::variant<Instruction, Literal, Identifier>;
|
using ElementaryOperation = boost::variant<Instruction, Literal, Identifier>;
|
||||||
|
|
||||||
@ -71,7 +74,6 @@ protected:
|
|||||||
ForLoop parseForLoop();
|
ForLoop parseForLoop();
|
||||||
/// Parses a functional expression that has to push exactly one stack element
|
/// Parses a functional expression that has to push exactly one stack element
|
||||||
Expression parseExpression();
|
Expression parseExpression();
|
||||||
static std::map<std::string, dev::eth::Instruction> const& instructions();
|
|
||||||
static std::map<dev::eth::Instruction, std::string> const& instructionNames();
|
static std::map<dev::eth::Instruction, std::string> const& instructionNames();
|
||||||
/// Parses an elementary operation, i.e. a literal, identifier or instruction.
|
/// Parses an elementary operation, i.e. a literal, identifier or instruction.
|
||||||
/// This will parse instructions even in strict mode as part of the full parser
|
/// This will parse instructions even in strict mode as part of the full parser
|
||||||
|
@ -23,6 +23,10 @@
|
|||||||
#include <libyul/optimiser/NameCollector.h>
|
#include <libyul/optimiser/NameCollector.h>
|
||||||
#include <libyul/AsmData.h>
|
#include <libyul/AsmData.h>
|
||||||
#include <libyul/Dialect.h>
|
#include <libyul/Dialect.h>
|
||||||
|
#include <libyul/backends/evm/EVMDialect.h>
|
||||||
|
#include <libyul/AsmParser.h>
|
||||||
|
|
||||||
|
#include <libevmasm/Instruction.h>
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace dev;
|
using namespace dev;
|
||||||
@ -42,7 +46,7 @@ NameDispenser::NameDispenser(Dialect const& _dialect, set<YulString> _usedNames)
|
|||||||
YulString NameDispenser::newName(YulString _nameHint)
|
YulString NameDispenser::newName(YulString _nameHint)
|
||||||
{
|
{
|
||||||
YulString name = _nameHint;
|
YulString name = _nameHint;
|
||||||
while (name.empty() || m_usedNames.count(name) || m_dialect.builtin(name))
|
while (illegalName(name))
|
||||||
{
|
{
|
||||||
m_counter++;
|
m_counter++;
|
||||||
name = YulString(_nameHint.str() + "_" + to_string(m_counter));
|
name = YulString(_nameHint.str() + "_" + to_string(m_counter));
|
||||||
@ -50,3 +54,12 @@ YulString NameDispenser::newName(YulString _nameHint)
|
|||||||
m_usedNames.emplace(name);
|
m_usedNames.emplace(name);
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool NameDispenser::illegalName(YulString _name)
|
||||||
|
{
|
||||||
|
if (_name.empty() || m_usedNames.count(_name) || m_dialect.builtin(_name))
|
||||||
|
return true;
|
||||||
|
if (dynamic_cast<EVMDialect const*>(&m_dialect))
|
||||||
|
return Parser::instructions().count(_name.str());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
@ -47,6 +47,7 @@ public:
|
|||||||
YulString newName(YulString _nameHint);
|
YulString newName(YulString _nameHint);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
bool illegalName(YulString _name);
|
||||||
|
|
||||||
Dialect const& m_dialect;
|
Dialect const& m_dialect;
|
||||||
std::set<YulString> m_usedNames;
|
std::set<YulString> m_usedNames;
|
||||||
|
@ -18,6 +18,8 @@
|
|||||||
#include <libyul/optimiser/VarNameCleaner.h>
|
#include <libyul/optimiser/VarNameCleaner.h>
|
||||||
#include <libyul/AsmData.h>
|
#include <libyul/AsmData.h>
|
||||||
#include <libyul/Dialect.h>
|
#include <libyul/Dialect.h>
|
||||||
|
#include <libyul/AsmParser.h>
|
||||||
|
#include <libyul/backends/evm/EVMDialect.h>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <cctype>
|
#include <cctype>
|
||||||
#include <climits>
|
#include <climits>
|
||||||
@ -93,7 +95,7 @@ void VarNameCleaner::operator()(Identifier& _identifier)
|
|||||||
YulString VarNameCleaner::findCleanName(YulString const& _name) const
|
YulString VarNameCleaner::findCleanName(YulString const& _name) const
|
||||||
{
|
{
|
||||||
auto newName = stripSuffix(_name);
|
auto newName = stripSuffix(_name);
|
||||||
if (newName != YulString{} && !isUsedName(newName))
|
if (!isUsedName(newName))
|
||||||
return newName;
|
return newName;
|
||||||
|
|
||||||
// create new name with suffix (by finding a free identifier)
|
// create new name with suffix (by finding a free identifier)
|
||||||
@ -108,7 +110,11 @@ YulString VarNameCleaner::findCleanName(YulString const& _name) const
|
|||||||
|
|
||||||
bool VarNameCleaner::isUsedName(YulString const& _name) const
|
bool VarNameCleaner::isUsedName(YulString const& _name) const
|
||||||
{
|
{
|
||||||
return m_dialect.builtin(_name) || m_usedNames.count(_name);
|
if (_name.empty() || m_dialect.builtin(_name) || m_usedNames.count(_name))
|
||||||
|
return true;
|
||||||
|
if (dynamic_cast<EVMDialect const*>(&m_dialect))
|
||||||
|
return Parser::instructions().count(_name.str());
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
YulString VarNameCleaner::stripSuffix(YulString const& _name) const
|
YulString VarNameCleaner::stripSuffix(YulString const& _name) const
|
||||||
|
@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
let mul_256 := 1
|
||||||
|
}
|
||||||
|
// ====
|
||||||
|
// step: varNameCleaner
|
||||||
|
// ----
|
||||||
|
// {
|
||||||
|
// let mul_1 := 1
|
||||||
|
// }
|
Loading…
Reference in New Issue
Block a user