mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Use different way to fall back to FunctionalInstruction for loose assembly.
This commit is contained in:
parent
9a00729ce7
commit
97fa21841d
@ -32,6 +32,7 @@
|
||||
|
||||
#include <libyul/AsmPrinter.h>
|
||||
#include <libyul/AsmData.h>
|
||||
#include <libyul/Dialect.h>
|
||||
#include <libyul/optimiser/ASTCopier.h>
|
||||
|
||||
#include <libdevcore/Whiskers.h>
|
||||
@ -50,13 +51,20 @@ struct CopyTranslate: public yul::ASTCopier
|
||||
{
|
||||
using ExternalRefsMap = std::map<yul::Identifier const*, InlineAssemblyAnnotation::ExternalIdentifierInfo>;
|
||||
|
||||
CopyTranslate(IRGenerationContext& _context, ExternalRefsMap const& _references):
|
||||
m_context(_context), m_references(_references) {}
|
||||
CopyTranslate(yul::Dialect const& _dialect, IRGenerationContext& _context, ExternalRefsMap const& _references):
|
||||
m_dialect(_dialect), m_context(_context), m_references(_references) {}
|
||||
|
||||
using ASTCopier::operator();
|
||||
|
||||
yul::YulString translateIdentifier(yul::YulString _name) override
|
||||
{
|
||||
// Strictly, the dialect used by inline assembly (m_dialect) could be different
|
||||
// from the Yul dialect we are compiling to. So we are assuming here that the builtin
|
||||
// functions are identical. This should not be a problem for now since everything
|
||||
// is EVM anyway.
|
||||
if (m_dialect.builtin(_name))
|
||||
return _name;
|
||||
else
|
||||
return yul::YulString{"usr$" + _name.str()};
|
||||
}
|
||||
|
||||
@ -80,6 +88,7 @@ struct CopyTranslate: public yul::ASTCopier
|
||||
}
|
||||
|
||||
private:
|
||||
yul::Dialect const& m_dialect;
|
||||
IRGenerationContext& m_context;
|
||||
ExternalRefsMap const& m_references;
|
||||
};
|
||||
@ -723,7 +732,7 @@ void IRGeneratorForStatements::endVisit(MemberAccess const& _memberAccess)
|
||||
|
||||
bool IRGeneratorForStatements::visit(InlineAssembly const& _inlineAsm)
|
||||
{
|
||||
CopyTranslate bodyCopier{m_context, _inlineAsm.annotation().externalReferences};
|
||||
CopyTranslate bodyCopier{_inlineAsm.dialect(), m_context, _inlineAsm.annotation().externalReferences};
|
||||
|
||||
yul::Statement modified = bodyCopier(_inlineAsm.operations());
|
||||
|
||||
|
@ -248,13 +248,6 @@ Statement Parser::parseStatement()
|
||||
if (elementary.type() == typeid(Identifier))
|
||||
{
|
||||
Identifier& identifier = boost::get<Identifier>(elementary);
|
||||
// Fallback from builtin function to Instruction for loose assembly.
|
||||
if (
|
||||
m_dialect.flavour == AsmFlavour::Loose &&
|
||||
instructions().count(identifier.name.str())
|
||||
)
|
||||
return Instruction{identifier.location, instructions().at(identifier.name.str())};
|
||||
else
|
||||
return ExpressionStatement{identifier.location, { move(identifier) }};
|
||||
}
|
||||
else if (elementary.type() == typeid(Literal))
|
||||
@ -405,11 +398,18 @@ Parser::ElementaryOperation Parser::parseElementaryOperation()
|
||||
// first search the set of builtins, then the instructions.
|
||||
if (m_dialect.builtin(literal))
|
||||
{
|
||||
// For builtins we already check here that they are followed by `(`.
|
||||
ret = FunctionCall{location(), Identifier{location(), literal}, {}};
|
||||
Identifier identifier{location(), literal};
|
||||
advance();
|
||||
expectToken(Token::LParen, false);
|
||||
return ret;
|
||||
// If the builtin is not followed by `(` and we are in loose mode,
|
||||
// fall back to instruction.
|
||||
if (
|
||||
m_dialect.flavour == AsmFlavour::Loose &&
|
||||
instructions().count(identifier.name.str()) &&
|
||||
m_scanner->currentToken() != Token::LParen
|
||||
)
|
||||
return Instruction{identifier.location, instructions().at(identifier.name.str())};
|
||||
else
|
||||
return FunctionCall{identifier.location, identifier, {}};
|
||||
}
|
||||
else if (m_dialect.flavour == AsmFlavour::Loose && instructions().count(literal.str()))
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user