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/AsmPrinter.h>
|
||||||
#include <libyul/AsmData.h>
|
#include <libyul/AsmData.h>
|
||||||
|
#include <libyul/Dialect.h>
|
||||||
#include <libyul/optimiser/ASTCopier.h>
|
#include <libyul/optimiser/ASTCopier.h>
|
||||||
|
|
||||||
#include <libdevcore/Whiskers.h>
|
#include <libdevcore/Whiskers.h>
|
||||||
@ -50,13 +51,20 @@ struct CopyTranslate: public yul::ASTCopier
|
|||||||
{
|
{
|
||||||
using ExternalRefsMap = std::map<yul::Identifier const*, InlineAssemblyAnnotation::ExternalIdentifierInfo>;
|
using ExternalRefsMap = std::map<yul::Identifier const*, InlineAssemblyAnnotation::ExternalIdentifierInfo>;
|
||||||
|
|
||||||
CopyTranslate(IRGenerationContext& _context, ExternalRefsMap const& _references):
|
CopyTranslate(yul::Dialect const& _dialect, IRGenerationContext& _context, ExternalRefsMap const& _references):
|
||||||
m_context(_context), m_references(_references) {}
|
m_dialect(_dialect), m_context(_context), m_references(_references) {}
|
||||||
|
|
||||||
using ASTCopier::operator();
|
using ASTCopier::operator();
|
||||||
|
|
||||||
yul::YulString translateIdentifier(yul::YulString _name) override
|
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()};
|
return yul::YulString{"usr$" + _name.str()};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -80,6 +88,7 @@ struct CopyTranslate: public yul::ASTCopier
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
yul::Dialect const& m_dialect;
|
||||||
IRGenerationContext& m_context;
|
IRGenerationContext& m_context;
|
||||||
ExternalRefsMap const& m_references;
|
ExternalRefsMap const& m_references;
|
||||||
};
|
};
|
||||||
@ -723,7 +732,7 @@ void IRGeneratorForStatements::endVisit(MemberAccess const& _memberAccess)
|
|||||||
|
|
||||||
bool IRGeneratorForStatements::visit(InlineAssembly const& _inlineAsm)
|
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());
|
yul::Statement modified = bodyCopier(_inlineAsm.operations());
|
||||||
|
|
||||||
|
@ -248,13 +248,6 @@ Statement Parser::parseStatement()
|
|||||||
if (elementary.type() == typeid(Identifier))
|
if (elementary.type() == typeid(Identifier))
|
||||||
{
|
{
|
||||||
Identifier& identifier = boost::get<Identifier>(elementary);
|
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) }};
|
return ExpressionStatement{identifier.location, { move(identifier) }};
|
||||||
}
|
}
|
||||||
else if (elementary.type() == typeid(Literal))
|
else if (elementary.type() == typeid(Literal))
|
||||||
@ -405,11 +398,18 @@ Parser::ElementaryOperation Parser::parseElementaryOperation()
|
|||||||
// first search the set of builtins, then the instructions.
|
// first search the set of builtins, then the instructions.
|
||||||
if (m_dialect.builtin(literal))
|
if (m_dialect.builtin(literal))
|
||||||
{
|
{
|
||||||
// For builtins we already check here that they are followed by `(`.
|
Identifier identifier{location(), literal};
|
||||||
ret = FunctionCall{location(), Identifier{location(), literal}, {}};
|
|
||||||
advance();
|
advance();
|
||||||
expectToken(Token::LParen, false);
|
// If the builtin is not followed by `(` and we are in loose mode,
|
||||||
return ret;
|
// 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()))
|
else if (m_dialect.flavour == AsmFlavour::Loose && instructions().count(literal.str()))
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user