Yul: Remove obsoleted FunctionalInstruction.

This commit is contained in:
Christian Parpart 2019-11-06 17:25:03 +01:00
parent 147120ba47
commit f15d47f165
41 changed files with 35 additions and 304 deletions

View File

@ -47,12 +47,6 @@ public:
}
void operator()(yul::Literal const&) {}
void operator()(yul::Identifier const&) {}
void operator()(yul::FunctionalInstruction const& _instr)
{
checkInstruction(_instr.location, _instr.instruction);
for (auto const& arg: _instr.arguments)
boost::apply_visitor(*this, arg);
}
void operator()(yul::ExpressionStatement const& _expr)
{
boost::apply_visitor(*this, _expr.expression);

View File

@ -179,22 +179,6 @@ bool AsmAnalyzer::operator()(Identifier const& _identifier)
return success;
}
bool AsmAnalyzer::operator()(FunctionalInstruction const& _instr)
{
solAssert(m_dialect.flavour != AsmFlavour::Yul, "");
bool success = true;
for (auto const& arg: _instr.arguments | boost::adaptors::reversed)
if (!expectExpression(arg))
success = false;
// Parser already checks that the number of arguments is correct.
auto const& info = instructionInfo(_instr.instruction);
solAssert(info.args == int(_instr.arguments.size()), "");
m_stackHeight += info.ret - info.args;
m_info.stackHeightInfo[&_instr] = m_stackHeight;
warnOnInstructions(_instr.instruction, _instr.location);
return success;
}
bool AsmAnalyzer::operator()(ExpressionStatement const& _statement)
{
int initialStackHeight = m_stackHeight;

View File

@ -82,7 +82,6 @@ public:
bool operator()(Instruction const&);
bool operator()(Literal const& _literal);
bool operator()(Identifier const&);
bool operator()(FunctionalInstruction const& _functionalInstruction);
bool operator()(ExpressionStatement const&);
bool operator()(Assignment const& _assignment);
bool operator()(VariableDeclaration const& _variableDeclaration);

View File

@ -56,8 +56,6 @@ struct Identifier { langutil::SourceLocation location; YulString name; };
/// a single stack slot and expects a single expression on the right hand returning
/// the same amount of items as the number of variables.
struct Assignment { langutil::SourceLocation location; std::vector<Identifier> variableNames; std::unique_ptr<Expression> value; };
/// Functional instruction, e.g. "mul(mload(20:u256), add(2:u256, x))"
struct FunctionalInstruction { langutil::SourceLocation location; dev::eth::Instruction instruction; std::vector<Expression> arguments; };
struct FunctionCall { langutil::SourceLocation location; Identifier functionName; std::vector<Expression> arguments; };
/// Statement that contains only a single expression
struct ExpressionStatement { langutil::SourceLocation location; Expression expression; };

View File

@ -32,7 +32,6 @@ struct Label;
struct Identifier;
struct Assignment;
struct VariableDeclaration;
struct FunctionalInstruction;
struct FunctionDefinition;
struct FunctionCall;
struct If;
@ -47,7 +46,7 @@ struct Block;
struct TypedName;
using Expression = boost::variant<FunctionalInstruction, FunctionCall, Identifier, Literal>;
using Expression = boost::variant<FunctionCall, Identifier, Literal>;
using Statement = boost::variant<ExpressionStatement, Assignment, VariableDeclaration, FunctionDefinition, If, Switch, ForLoop, Break, Continue, Leave, Block>;
}

View File

@ -462,84 +462,15 @@ FunctionDefinition Parser::parseFunctionDefinition()
Expression Parser::parseCall(Parser::ElementaryOperation&& _initialOp)
{
RecursionGuard recursionGuard(*this);
if (_initialOp.type() == typeid(Instruction))
{
solAssert(m_dialect.flavour != AsmFlavour::Yul, "Instructions are invalid in Yul");
Instruction& instruction = boost::get<Instruction>(_initialOp);
FunctionalInstruction ret;
ret.instruction = instruction.instruction;
ret.location = std::move(instruction.location);
dev::eth::Instruction instr = ret.instruction;
dev::eth::InstructionInfo instrInfo = instructionInfo(instr);
if (dev::eth::isDupInstruction(instr))
fatalParserError("DUPi instructions not allowed for functional notation");
if (dev::eth::isSwapInstruction(instr))
fatalParserError("SWAPi instructions not allowed for functional notation");
expectToken(Token::LParen);
unsigned args = unsigned(instrInfo.args);
for (unsigned i = 0; i < args; ++i)
{
/// check for premature closing parentheses
if (currentToken() == Token::RParen)
fatalParserError(string(
"Expected expression (instruction \"" +
instructionNames().at(instr) +
"\" expects " +
to_string(args) +
" arguments)"
));
ret.arguments.emplace_back(parseExpression());
if (i != args - 1)
{
if (currentToken() != Token::Comma)
fatalParserError(string(
"Expected ',' (instruction \"" +
instructionNames().at(instr) +
"\" expects " +
to_string(args) +
" arguments)"
));
else
advance();
}
}
ret.location.end = endPosition();
if (currentToken() == Token::Comma)
fatalParserError(string(
"Expected ')' (instruction \"" +
instructionNames().at(instr) +
"\" expects " +
to_string(args) +
" arguments)"
));
expectToken(Token::RParen);
return ret;
}
else if (_initialOp.type() == typeid(Identifier) || _initialOp.type() == typeid(FunctionCall))
FunctionCall ret;
if (_initialOp.type() == typeid(Identifier))
{
FunctionCall ret;
if (_initialOp.type() == typeid(Identifier))
{
ret.functionName = std::move(boost::get<Identifier>(_initialOp));
ret.location = ret.functionName.location;
}
else
ret = std::move(boost::get<FunctionCall>(_initialOp));
expectToken(Token::LParen);
if (currentToken() != Token::RParen)
{
ret.arguments.emplace_back(parseExpression());
while (currentToken() != Token::RParen)
{
expectToken(Token::Comma);
ret.arguments.emplace_back(parseExpression());
}
}
ret.location.end = endPosition();
expectToken(Token::RParen);
return ret;
ret.functionName = std::move(boost::get<Identifier>(_initialOp));
ret.location = ret.functionName.location;
}
else if (_initialOp.type() == typeid(FunctionCall))
ret = std::move(boost::get<FunctionCall>(_initialOp));
else
fatalParserError(
m_dialect.flavour == AsmFlavour::Yul ?
@ -547,7 +478,19 @@ Expression Parser::parseCall(Parser::ElementaryOperation&& _initialOp)
"Assembly instruction or function name required in front of \"(\")"
);
return {};
expectToken(Token::LParen);
if (currentToken() != Token::RParen)
{
ret.arguments.emplace_back(parseExpression());
while (currentToken() != Token::RParen)
{
expectToken(Token::Comma);
ret.arguments.emplace_back(parseExpression());
}
}
ret.location.end = endPosition();
expectToken(Token::RParen);
return ret;
}
TypedName Parser::parseTypedName()

View File

@ -88,19 +88,6 @@ string AsmPrinter::operator()(Identifier const& _identifier) const
return _identifier.name.str();
}
string AsmPrinter::operator()(FunctionalInstruction const& _functionalInstruction) const
{
solAssert(!m_yul, "");
solAssert(isValidInstruction(_functionalInstruction.instruction), "Invalid instruction");
return
boost::to_lower_copy(instructionInfo(_functionalInstruction.instruction).name) +
"(" +
boost::algorithm::join(
_functionalInstruction.arguments | boost::adaptors::transformed(boost::apply_visitor(*this)),
", ") +
")";
}
string AsmPrinter::operator()(ExpressionStatement const& _statement) const
{
return boost::apply_visitor(*this, _statement.expression);

View File

@ -38,7 +38,6 @@ public:
std::string operator()(Literal const& _literal) const;
std::string operator()(Identifier const& _identifier) const;
std::string operator()(FunctionalInstruction const& _functionalInstruction) const;
std::string operator()(ExpressionStatement const& _expr) const;
std::string operator()(Assignment const& _assignment) const;
std::string operator()(VariableDeclaration const& _variableDeclaration) const;

View File

@ -51,7 +51,6 @@ public:
bool operator()(Literal const&) { return true; }
bool operator()(Identifier const&) { return true; }
bool operator()(FunctionalInstruction const&) { return true; }
bool operator()(ExpressionStatement const& _expr);
bool operator()(Assignment const&) { return true; }
bool operator()(VariableDeclaration const& _variableDeclaration);

View File

@ -69,10 +69,6 @@ struct MiniEVMInterpreter: boost::static_visitor<u256>
return 0;
}
u256 operator()(FunctionalInstruction const& _instr)
{
return eval(_instr.instruction, _instr.arguments);
}
u256 operator()(FunctionCall const& _funCall)
{
BuiltinFunctionForEVM const* fun = m_dialect.builtin(_funCall.functionName.name);

View File

@ -303,40 +303,6 @@ void CodeTransform::operator()(FunctionCall const& _call)
}
}
void CodeTransform::operator()(FunctionalInstruction const& _instruction)
{
if (m_evm15 && (
_instruction.instruction == dev::eth::Instruction::JUMP ||
_instruction.instruction == dev::eth::Instruction::JUMPI
))
{
bool const isJumpI = _instruction.instruction == dev::eth::Instruction::JUMPI;
if (isJumpI)
{
solAssert(_instruction.arguments.size() == 2, "");
visitExpression(_instruction.arguments.at(1));
}
else
{
solAssert(_instruction.arguments.size() == 1, "");
}
m_assembly.setSourceLocation(_instruction.location);
auto label = labelFromIdentifier(boost::get<Identifier>(_instruction.arguments.at(0)));
if (isJumpI)
m_assembly.appendJumpToIf(label);
else
m_assembly.appendJumpTo(label);
}
else
{
for (auto const& arg: _instruction.arguments | boost::adaptors::reversed)
visitExpression(arg);
m_assembly.setSourceLocation(_instruction.location);
m_assembly.appendInstruction(_instruction.instruction);
}
checkStackHeight(&_instruction);
}
void CodeTransform::operator()(Identifier const& _identifier)
{
m_assembly.setSourceLocation(_identifier.location);

View File

@ -175,7 +175,6 @@ public:
void operator()(Instruction const& _instruction);
void operator()(Literal const& _literal);
void operator()(Identifier const& _identifier);
void operator()(FunctionalInstruction const& _instr);
void operator()(FunctionCall const&);
void operator()(ExpressionStatement const& _statement);
void operator()(Assignment const& _assignment);

View File

@ -85,12 +85,6 @@ void GasMeterVisitor::operator()(FunctionCall const& _funCall)
yulAssert(false, "Functions not implemented.");
}
void GasMeterVisitor::operator()(FunctionalInstruction const& _fun)
{
ASTWalker::operator()(_fun);
instructionCostsInternal(_fun.instruction);
}
void GasMeterVisitor::operator()(Literal const& _lit)
{
m_runGas += dev::eth::GasMeter::runGas(dev::eth::Instruction::PUSH1);

View File

@ -81,7 +81,6 @@ public:
{}
void operator()(FunctionCall const& _funCall) override;
void operator()(FunctionalInstruction const& _instr) override;
void operator()(Literal const& _literal) override;
void operator()(Identifier const& _identifier) override;

View File

@ -110,12 +110,6 @@ wasm::Expression EWasmCodeTransform::operator()(ExpressionStatement const& _stat
return visitReturnByValue(_statement.expression);
}
wasm::Expression EWasmCodeTransform::operator()(FunctionalInstruction const& _f)
{
yulAssert(false, "EVM instruction in ewasm code: " + eth::instructionInfo(_f.instruction).name);
return {};
}
wasm::Expression EWasmCodeTransform::operator()(FunctionCall const& _call)
{
bool typeConversionNeeded = false;

View File

@ -40,7 +40,6 @@ public:
public:
wasm::Expression operator()(yul::Literal const& _literal);
wasm::Expression operator()(yul::Identifier const& _identifier);
wasm::Expression operator()(yul::FunctionalInstruction const& _instr);
wasm::Expression operator()(yul::FunctionCall const&);
wasm::Expression operator()(yul::ExpressionStatement const& _statement);
wasm::Expression operator()(yul::Assignment const& _assignment);

View File

@ -37,11 +37,6 @@ void WordSizeTransform::operator()(FunctionDefinition& _fd)
(*this)(_fd.body);
}
void WordSizeTransform::operator()(FunctionalInstruction& _ins)
{
rewriteFunctionCallArguments(_ins.arguments);
}
void WordSizeTransform::operator()(FunctionCall& _fc)
{
if (BuiltinFunction const* fun = m_inputDialect.builtin(_fc.functionName.name))
@ -111,10 +106,7 @@ void WordSizeTransform::operator()(Block& _block)
return {std::move(ret)};
}
if (
!varDecl.value ||
varDecl.value->type() == typeid(FunctionalInstruction) ||
varDecl.value->type() == typeid(FunctionCall)
if (!varDecl.value || varDecl.value->type() == typeid(FunctionCall)
)
{
if (varDecl.value) visit(*varDecl.value);
@ -171,10 +163,7 @@ void WordSizeTransform::operator()(Block& _block)
return {std::move(ret)};
}
if (
assignment.value->type() == typeid(FunctionalInstruction) ||
assignment.value->type() == typeid(FunctionCall)
)
if (assignment.value->type() == typeid(FunctionCall))
{
if (assignment.value) visit(*assignment.value);
rewriteIdentifierList(assignment.variableNames);

View File

@ -37,11 +37,11 @@ namespace yul
* but wasm only supports values up to 64 bits, so we use four u64 values to simulate
* one u256 value.
*
* For FunctionalInstruction that accepts or returns u256 values, they accepts or returns
* For FunctionCall that accepts or returns u256 values, they accepts or returns
* four times the number of values after this transformation, with the order of significance,
* from the most significant to the least significant.
*
* For example, the FunctionalInstruction MUL supplied by code generator
* For example, the FunctionCall MUL supplied by code generator
* should take 8 arguments and return 4 values (instead of 2 and 1) after this transformation.
*
* mul(a1, a2, a3, a4, b1, b2, b3, b4) -> c1, c2, c3, c4
@ -61,7 +61,6 @@ class WordSizeTransform: public ASTModifier
{
public:
void operator()(FunctionDefinition&) override;
void operator()(FunctionalInstruction&) override;
void operator()(FunctionCall&) override;
void operator()(If&) override;
void operator()(Switch&) override;

View File

@ -62,15 +62,6 @@ Expression ASTCopier::operator()(FunctionCall const& _call)
};
}
Expression ASTCopier::operator()(FunctionalInstruction const& _instruction)
{
return FunctionalInstruction{
_instruction.location,
_instruction.instruction,
translateVector(_instruction.arguments)
};
}
Expression ASTCopier::operator()(Identifier const& _identifier)
{
return translate(_identifier);

View File

@ -40,7 +40,6 @@ public:
virtual ~ExpressionCopier() = default;
virtual Expression operator()(Literal const& _literal) = 0;
virtual Expression operator()(Identifier const& _identifier) = 0;
virtual Expression operator()(FunctionalInstruction const& _instr) = 0;
virtual Expression operator()(FunctionCall const&) = 0;
};
@ -71,7 +70,6 @@ public:
virtual ~ASTCopier() = default;
Expression operator()(Literal const& _literal) override;
Expression operator()(Identifier const& _identifier) override;
Expression operator()(FunctionalInstruction const& _instr) override;
Expression operator()(FunctionCall const&) override;
Statement operator()(ExpressionStatement const& _statement) override;
Statement operator()(Assignment const& _assignment) override;

View File

@ -28,11 +28,6 @@ using namespace std;
using namespace dev;
using namespace yul;
void ASTWalker::operator()(FunctionalInstruction const& _instr)
{
walkVector(_instr.arguments | boost::adaptors::reversed);
}
void ASTWalker::operator()(FunctionCall const& _funCall)
{
// Does not visit _funCall.functionName on purpose
@ -102,11 +97,6 @@ void ASTWalker::visit(Expression const& _e)
boost::apply_visitor(*this, _e);
}
void ASTModifier::operator()(FunctionalInstruction& _instr)
{
walkVector(_instr.arguments | boost::adaptors::reversed);
}
void ASTModifier::operator()(FunctionCall& _funCall)
{
// Does not visit _funCall.functionName on purpose

View File

@ -44,7 +44,6 @@ public:
virtual ~ASTWalker() = default;
virtual void operator()(Literal const&) {}
virtual void operator()(Identifier const&) {}
virtual void operator()(FunctionalInstruction const& _instr);
virtual void operator()(FunctionCall const& _funCall);
virtual void operator()(ExpressionStatement const& _statement);
virtual void operator()(Assignment const& _assignment);
@ -79,7 +78,6 @@ public:
virtual ~ASTModifier() = default;
virtual void operator()(Literal&) {}
virtual void operator()(Identifier&) {}
virtual void operator()(FunctionalInstruction& _instr);
virtual void operator()(FunctionCall& _funCall);
virtual void operator()(ExpressionStatement& _statement);
virtual void operator()(Assignment& _assignment);

View File

@ -76,14 +76,6 @@ void BlockHasher::operator()(Identifier const& _identifier)
hash64(it->second.id);
}
void BlockHasher::operator()(FunctionalInstruction const& _instr)
{
hash64(compileTimeLiteralHash("FunctionalInstruction"));
hash8(static_cast<std::underlying_type_t<eth::Instruction>>(_instr.instruction));
hash64(_instr.arguments.size());
ASTWalker::operator()(_instr);
}
void BlockHasher::operator()(FunctionCall const& _funCall)
{
hash64(compileTimeLiteralHash("FunctionCall"));

View File

@ -49,7 +49,6 @@ public:
void operator()(Literal const&) override;
void operator()(Identifier const&) override;
void operator()(FunctionalInstruction const& _instr) override;
void operator()(FunctionCall const& _funCall) override;
void operator()(ExpressionStatement const& _statement) override;
void operator()(Assignment const& _assignment) override;

View File

@ -36,14 +36,6 @@ map<YulString, set<YulString>> CallGraphGenerator::callGraph(Block const& _ast)
return std::move(gen.m_callGraph);
}
void CallGraphGenerator::operator()(FunctionalInstruction const& _functionalInstruction)
{
string name = dev::eth::instructionInfo(_functionalInstruction.instruction).name;
std::transform(name.begin(), name.end(), name.begin(), [](unsigned char _c) { return tolower(_c); });
m_callGraph[m_currentFunction].insert(YulString{name});
ASTWalker::operator()(_functionalInstruction);
}
void CallGraphGenerator::operator()(FunctionCall const& _functionCall)
{
m_callGraph[m_currentFunction].insert(_functionCall.functionName.name);

View File

@ -42,7 +42,6 @@ public:
static std::map<YulString, std::set<YulString>> callGraph(Block const& _ast);
using ASTWalker::operator();
void operator()(FunctionalInstruction const& _functionalInstruction) override;
void operator()(FunctionCall const& _functionCall) override;
void operator()(FunctionDefinition const& _functionDefinition) override;

View File

@ -40,11 +40,6 @@ void ExpressionJoiner::run(OptimiserStepContext&, Block& _ast)
}
void ExpressionJoiner::operator()(FunctionalInstruction& _instruction)
{
handleArguments(_instruction.arguments);
}
void ExpressionJoiner::operator()(FunctionCall& _funCall)
{
handleArguments(_funCall.arguments);

View File

@ -78,7 +78,6 @@ private:
explicit ExpressionJoiner(Block& _ast);
void operator()(Block& _block) override;
void operator()(FunctionalInstruction&) override;
void operator()(FunctionCall&) override;
using ASTModifier::visit;

View File

@ -41,12 +41,6 @@ void ExpressionSplitter::run(OptimiserStepContext& _context, Block& _ast)
ExpressionSplitter{_context.dialect, _context.dispenser}(_ast);
}
void ExpressionSplitter::operator()(FunctionalInstruction& _instruction)
{
for (auto& arg: _instruction.arguments | boost::adaptors::reversed)
outlineExpression(arg);
}
void ExpressionSplitter::operator()(FunctionCall& _funCall)
{
if (BuiltinFunction const* builtin = m_dialect.builtin(_funCall.functionName.name))

View File

@ -61,7 +61,6 @@ public:
static constexpr char const* name{"ExpressionSplitter"};
static void run(OptimiserStepContext&, Block& _ast);
void operator()(FunctionalInstruction&) override;
void operator()(FunctionCall&) override;
void operator()(If&) override;
void operator()(Switch&) override;

View File

@ -77,9 +77,6 @@ Expression KnowledgeBase::simplify(Expression _expression)
if (_expression.type() == typeid(FunctionCall))
for (Expression& arg: boost::get<FunctionCall>(_expression).arguments)
arg = simplify(arg);
else if (_expression.type() == typeid(FunctionalInstruction))
for (Expression& arg: boost::get<FunctionalInstruction>(_expression).arguments)
arg = simplify(arg);
if (auto match = SimplificationRules::findFirstMatch(_expression, m_dialect, m_variableValues))
return simplify(match->action().toExpression(locationOf(_expression)));

View File

@ -55,11 +55,6 @@ void LoadResolver::visit(Expression& _e)
if (builtin->instruction)
tryResolve(_e, *builtin->instruction, funCall.arguments);
}
else if (_e.type() == typeid(FunctionalInstruction))
{
FunctionalInstruction const& instruction = boost::get<FunctionalInstruction>(_e);
tryResolve(_e, instruction.instruction, instruction.arguments);
}
}
void LoadResolver::tryResolve(

View File

@ -120,13 +120,6 @@ void CodeCost::operator()(FunctionCall const& _funCall)
m_cost += 49;
}
void CodeCost::operator()(FunctionalInstruction const& _instr)
{
yulAssert(m_cost >= 1, "Should assign cost one in visit(Expression).");
addInstructionCost(_instr.instruction);
ASTWalker::operator()(_instr);
}
void CodeCost::operator()(Literal const& _literal)
{
yulAssert(m_cost >= 1, "Should assign cost one in visit(Expression).");

View File

@ -81,7 +81,6 @@ private:
CodeCost(Dialect const& _dialect): m_dialect(_dialect) {}
void operator()(FunctionCall const& _funCall) override;
void operator()(FunctionalInstruction const& _instr) override;
void operator()(Literal const& _literal) override;
void visit(Statement const& _statement) override;
void visit(Expression const& _expression) override;

View File

@ -61,13 +61,6 @@ SideEffectsCollector::SideEffectsCollector(
operator()(_ast);
}
void SideEffectsCollector::operator()(FunctionalInstruction const& _instr)
{
ASTWalker::operator()(_instr);
m_sideEffects += EVMDialect::sideEffectsOfInstruction(_instr.instruction);
}
void SideEffectsCollector::operator()(FunctionCall const& _functionCall)
{
ASTWalker::operator()(_functionCall);
@ -88,14 +81,6 @@ bool MSizeFinder::containsMSize(Dialect const& _dialect, Block const& _ast)
return finder.m_msizeFound;
}
void MSizeFinder::operator()(FunctionalInstruction const& _instr)
{
ASTWalker::operator()(_instr);
if (_instr.instruction == eth::Instruction::MSIZE)
m_msizeFound = true;
}
void MSizeFinder::operator()(FunctionCall const& _functionCall)
{
ASTWalker::operator()(_functionCall);
@ -181,11 +166,7 @@ TerminationFinder::ControlFlow TerminationFinder::controlFlowKind(Statement cons
bool TerminationFinder::isTerminatingBuiltin(ExpressionStatement const& _exprStmnt)
{
if (_exprStmnt.expression.type() == typeid(FunctionalInstruction))
return eth::SemanticInformation::terminatesControlFlow(
boost::get<FunctionalInstruction>(_exprStmnt.expression).instruction
);
else if (_exprStmnt.expression.type() == typeid(FunctionCall))
if (_exprStmnt.expression.type() == typeid(FunctionCall))
if (auto const* dialect = dynamic_cast<EVMDialect const*>(&m_dialect))
if (auto const* builtin = dialect->builtin(boost::get<FunctionCall>(_exprStmnt.expression).functionName.name))
if (builtin->instruction)

View File

@ -54,7 +54,6 @@ public:
);
using ASTWalker::operator();
void operator()(FunctionalInstruction const& _functionalInstruction) override;
void operator()(FunctionCall const& _functionCall) override;
bool movable() const { return m_sideEffects.movable; }
@ -104,7 +103,6 @@ public:
static bool containsMSize(Dialect const& _dialect, Block const& _ast);
using ASTWalker::operator();
void operator()(FunctionalInstruction const& _instr);
void operator()(FunctionCall const& _funCall);
private:

View File

@ -67,9 +67,7 @@ bool SimplificationRules::isInitialized() const
std::optional<std::pair<dev::eth::Instruction, vector<Expression> const*>>
SimplificationRules::instructionAndArguments(Dialect const& _dialect, Expression const& _expr)
{
if (_expr.type() == typeid(FunctionalInstruction))
return make_pair(boost::get<FunctionalInstruction>(_expr).instruction, &boost::get<FunctionalInstruction>(_expr).arguments);
else if (_expr.type() == typeid(FunctionCall))
if (_expr.type() == typeid(FunctionCall))
if (auto const* dialect = dynamic_cast<EVMDialect const*>(&_dialect))
if (auto const* builtin = dialect->builtin(boost::get<FunctionCall>(_expr).functionName.name))
if (builtin->instruction)
@ -225,8 +223,15 @@ Expression Pattern::toExpression(SourceLocation const& _location) const
vector<Expression> arguments;
for (auto const& arg: m_arguments)
arguments.emplace_back(arg.toExpression(_location));
// TODO convert to FunctionCall
return FunctionalInstruction{_location, m_instruction, std::move(arguments)};
string name = instructionInfo(m_instruction).name;
transform(begin(name), end(name), begin(name), [](auto _c) { return tolower(_c); });
return FunctionCall{
_location,
Identifier{_location, YulString{name}},
std::move(arguments)
};
}
assertThrow(false, OptimizerException, "Pattern of kind 'any', but no match group.");
}

View File

@ -46,15 +46,6 @@ bool SyntacticallyEqual::operator()(Statement const& _lhs, Statement const& _rhs
}, _lhs, _rhs);
}
bool SyntacticallyEqual::expressionEqual(FunctionalInstruction const& _lhs, FunctionalInstruction const& _rhs)
{
return
_lhs.instruction == _rhs.instruction &&
containerEqual(_lhs.arguments, _rhs.arguments, [this](Expression const& _lhsExpr, Expression const& _rhsExpr) -> bool {
return (*this)(_lhsExpr, _rhsExpr);
});
}
bool SyntacticallyEqual::expressionEqual(FunctionCall const& _lhs, FunctionCall const& _rhs)
{
return

View File

@ -42,7 +42,6 @@ public:
bool operator()(Expression const& _lhs, Expression const& _rhs);
bool operator()(Statement const& _lhs, Statement const& _rhs);
bool expressionEqual(FunctionalInstruction const& _lhs, FunctionalInstruction const& _rhs);
bool expressionEqual(FunctionCall const& _lhs, FunctionCall const& _rhs);
bool expressionEqual(Identifier const& _lhs, Identifier const& _rhs);
bool expressionEqual(Literal const& _lhs, Literal const& _rhs);

View File

@ -227,15 +227,6 @@ void ExpressionEvaluator::operator()(Identifier const& _identifier)
setValue(m_variables.at(_identifier.name));
}
void ExpressionEvaluator::operator()(FunctionalInstruction const& _instr)
{
evaluateArgs(_instr.arguments);
EVMInstructionInterpreter interpreter(m_state);
// The instruction might also return nothing, but it does not
// hurt to set the value in that case.
setValue(interpreter.eval(_instr.instruction, values()));
}
void ExpressionEvaluator::operator()(FunctionCall const& _funCall)
{
evaluateArgs(_funCall.arguments);

View File

@ -169,7 +169,6 @@ public:
void operator()(Literal const&) override;
void operator()(Identifier const&) override;
void operator()(FunctionalInstruction const& _instr) override;
void operator()(FunctionCall const& _funCall) override;
/// Asserts that the expression has exactly one value and returns it.