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/ir/IRGenerationContext.h>
|
||||||
#include <libsolidity/codegen/YulUtilFunctions.h>
|
#include <libsolidity/codegen/YulUtilFunctions.h>
|
||||||
|
|
||||||
|
#include <libyul/AsmPrinter.h>
|
||||||
|
#include <libyul/AsmData.h>
|
||||||
|
#include <libyul/optimiser/ASTCopier.h>
|
||||||
|
|
||||||
#include <libdevcore/StringUtils.h>
|
#include <libdevcore/StringUtils.h>
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace dev;
|
using namespace dev;
|
||||||
using namespace dev::solidity;
|
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)
|
bool IRGeneratorForStatements::visit(VariableDeclarationStatement const& _varDeclStatement)
|
||||||
{
|
{
|
||||||
for (auto const& decl: _varDeclStatement.declarations())
|
for (auto const& decl: _varDeclStatement.declarations())
|
||||||
@ -179,6 +228,18 @@ bool IRGeneratorForStatements::visit(FunctionCall const& _functionCall)
|
|||||||
return false;
|
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)
|
bool IRGeneratorForStatements::visit(Identifier const& _identifier)
|
||||||
{
|
{
|
||||||
Declaration const* declaration = _identifier.annotation().referencedDeclaration;
|
Declaration const* declaration = _identifier.annotation().referencedDeclaration;
|
||||||
|
@ -48,6 +48,7 @@ public:
|
|||||||
bool visit(Assignment const& _assignment) override;
|
bool visit(Assignment const& _assignment) override;
|
||||||
void endVisit(BinaryOperation const& _binOp) override;
|
void endVisit(BinaryOperation const& _binOp) override;
|
||||||
bool visit(FunctionCall const& _funCall) override;
|
bool visit(FunctionCall const& _funCall) override;
|
||||||
|
bool visit(InlineAssembly const& _inlineAsm) override;
|
||||||
bool visit(Identifier const& _identifier) override;
|
bool visit(Identifier const& _identifier) override;
|
||||||
bool visit(Literal const& _literal) override;
|
bool visit(Literal const& _literal) override;
|
||||||
|
|
||||||
|
@ -91,7 +91,7 @@ Expression ASTCopier::operator()(FunctionalInstruction const& _instruction)
|
|||||||
|
|
||||||
Expression ASTCopier::operator()(Identifier const& _identifier)
|
Expression ASTCopier::operator()(Identifier const& _identifier)
|
||||||
{
|
{
|
||||||
return Identifier{_identifier.location, translateIdentifier(_identifier.name)};
|
return translate(_identifier);
|
||||||
}
|
}
|
||||||
|
|
||||||
Expression ASTCopier::operator()(Literal const& _literal)
|
Expression ASTCopier::operator()(Literal const& _literal)
|
||||||
|
@ -104,7 +104,7 @@ protected:
|
|||||||
|
|
||||||
Block translate(Block const& _block);
|
Block translate(Block const& _block);
|
||||||
Case translate(Case const& _case);
|
Case translate(Case const& _case);
|
||||||
Identifier translate(Identifier const& _identifier);
|
virtual Identifier translate(Identifier const& _identifier);
|
||||||
Literal translate(Literal const& _literal);
|
Literal translate(Literal const& _literal);
|
||||||
TypedName translate(TypedName const& _typedName);
|
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