mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
commit
b02fbc5d02
@ -23,12 +23,61 @@
|
||||
#include <libsolidity/codegen/ir/IRGenerationContext.h>
|
||||
#include <libsolidity/codegen/YulUtilFunctions.h>
|
||||
|
||||
#include <libyul/AsmPrinter.h>
|
||||
#include <libyul/AsmData.h>
|
||||
#include <libyul/optimiser/ASTCopier.h>
|
||||
|
||||
#include <libdevcore/StringUtils.h>
|
||||
|
||||
using namespace std;
|
||||
using namespace dev;
|
||||
using namespace dev::solidity;
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
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) {}
|
||||
|
||||
using ASTCopier::operator();
|
||||
|
||||
yul::YulString translateIdentifier(yul::YulString _name) override
|
||||
{
|
||||
return yul::YulString{"usr$" + _name.str()};
|
||||
}
|
||||
|
||||
yul::Identifier translate(yul::Identifier const& _identifier) override
|
||||
{
|
||||
if (!m_references.count(&_identifier))
|
||||
return ASTCopier::translate(_identifier);
|
||||
|
||||
auto const& reference = m_references.at(&_identifier);
|
||||
auto const varDecl = dynamic_cast<VariableDeclaration const*>(reference.declaration);
|
||||
solUnimplementedAssert(varDecl, "");
|
||||
solUnimplementedAssert(
|
||||
reference.isOffset == false && reference.isSlot == false,
|
||||
""
|
||||
);
|
||||
|
||||
return yul::Identifier{
|
||||
_identifier.location,
|
||||
yul::YulString{m_context.variableName(*varDecl)}
|
||||
};
|
||||
}
|
||||
|
||||
private:
|
||||
IRGenerationContext& m_context;
|
||||
ExternalRefsMap const& m_references;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool IRGeneratorForStatements::visit(VariableDeclarationStatement const& _varDeclStatement)
|
||||
{
|
||||
for (auto const& decl: _varDeclStatement.declarations())
|
||||
@ -179,6 +228,18 @@ bool IRGeneratorForStatements::visit(FunctionCall const& _functionCall)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool IRGeneratorForStatements::visit(InlineAssembly const& _inlineAsm)
|
||||
{
|
||||
CopyTranslate bodyCopier{m_context, _inlineAsm.annotation().externalReferences};
|
||||
|
||||
yul::Statement modified = bodyCopier(_inlineAsm.operations());
|
||||
|
||||
solAssert(modified.type() == typeid(yul::Block), "");
|
||||
|
||||
m_code << yul::AsmPrinter()(boost::get<yul::Block>(std::move(modified))) << "\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
bool IRGeneratorForStatements::visit(Identifier const& _identifier)
|
||||
{
|
||||
Declaration const* declaration = _identifier.annotation().referencedDeclaration;
|
||||
|
@ -48,6 +48,7 @@ public:
|
||||
bool visit(Assignment const& _assignment) override;
|
||||
void endVisit(BinaryOperation const& _binOp) override;
|
||||
bool visit(FunctionCall const& _funCall) override;
|
||||
bool visit(InlineAssembly const& _inlineAsm) override;
|
||||
bool visit(Identifier const& _identifier) override;
|
||||
bool visit(Literal const& _literal) override;
|
||||
|
||||
|
@ -91,7 +91,7 @@ Expression ASTCopier::operator()(FunctionalInstruction const& _instruction)
|
||||
|
||||
Expression ASTCopier::operator()(Identifier const& _identifier)
|
||||
{
|
||||
return Identifier{_identifier.location, translateIdentifier(_identifier.name)};
|
||||
return translate(_identifier);
|
||||
}
|
||||
|
||||
Expression ASTCopier::operator()(Literal const& _literal)
|
||||
|
@ -104,7 +104,7 @@ protected:
|
||||
|
||||
Block translate(Block const& _block);
|
||||
Case translate(Case const& _case);
|
||||
Identifier translate(Identifier const& _identifier);
|
||||
virtual Identifier translate(Identifier const& _identifier);
|
||||
Literal translate(Literal const& _literal);
|
||||
TypedName translate(TypedName const& _typedName);
|
||||
|
||||
|
17
test/libsolidity/semanticTests/viaYul/simple_inline_asm.sol
Normal file
17
test/libsolidity/semanticTests/viaYul/simple_inline_asm.sol
Normal file
@ -0,0 +1,17 @@
|
||||
contract C {
|
||||
function f() public pure returns (uint32 x) {
|
||||
uint32 a;
|
||||
uint32 b;
|
||||
uint32 c;
|
||||
assembly {
|
||||
a := 1
|
||||
b := 2
|
||||
c := 3
|
||||
}
|
||||
x = a + b + c;
|
||||
}
|
||||
}
|
||||
// ====
|
||||
// compileViaYul: true
|
||||
// ----
|
||||
// f() -> 6
|
23
test/libsolidity/semanticTests/viaYul/various_inline_asm.sol
Normal file
23
test/libsolidity/semanticTests/viaYul/various_inline_asm.sol
Normal file
@ -0,0 +1,23 @@
|
||||
contract C {
|
||||
function f() public pure returns (uint32 x) {
|
||||
uint32 a;
|
||||
uint32 b;
|
||||
uint32 c;
|
||||
assembly {
|
||||
function myAwesomeFunction(param) -> returnMe {
|
||||
let localVar := 10
|
||||
returnMe := add(localVar, param)
|
||||
}
|
||||
let abc := sub(10, a)
|
||||
let xyz := 20
|
||||
a := abc
|
||||
b := myAwesomeFunction(30)
|
||||
c := xyz
|
||||
}
|
||||
x = a + b + c;
|
||||
}
|
||||
}
|
||||
// ====
|
||||
// compileViaYul: true
|
||||
// ----
|
||||
// f() -> 70
|
Loading…
Reference in New Issue
Block a user