mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Isolating libyul library API into its own namespace yul
.
This commit is contained in:
parent
3734f40d31
commit
ec47c8946b
@ -273,7 +273,7 @@ bool ReferencesResolver::visit(InlineAssembly const& _inlineAssembly)
|
||||
ErrorList errors;
|
||||
ErrorReporter errorsIgnored(errors);
|
||||
yul::ExternalIdentifierAccess::Resolver resolver =
|
||||
[&](assembly::Identifier const& _identifier, yul::IdentifierContext, bool _crossesFunctionBoundary) {
|
||||
[&](yul::Identifier const& _identifier, yul::IdentifierContext, bool _crossesFunctionBoundary) {
|
||||
auto declarations = m_resolver.nameFromCurrentScope(_identifier.name.str());
|
||||
bool isSlot = boost::algorithm::ends_with(_identifier.name.str(), "_slot");
|
||||
bool isOffset = boost::algorithm::ends_with(_identifier.name.str(), "_offset");
|
||||
@ -314,9 +314,9 @@ bool ReferencesResolver::visit(InlineAssembly const& _inlineAssembly)
|
||||
|
||||
// Will be re-generated later with correct information
|
||||
// We use the latest EVM version because we will re-run it anyway.
|
||||
assembly::AsmAnalysisInfo analysisInfo;
|
||||
yul::AsmAnalysisInfo analysisInfo;
|
||||
boost::optional<Error::Type> errorTypeForLoose = Error::Type::SyntaxError;
|
||||
assembly::AsmAnalyzer(analysisInfo, errorsIgnored, EVMVersion(), errorTypeForLoose, assembly::AsmFlavour::Loose, resolver).analyze(_inlineAssembly.operations());
|
||||
yul::AsmAnalyzer(analysisInfo, errorsIgnored, EVMVersion(), errorTypeForLoose, yul::AsmFlavour::Loose, resolver).analyze(_inlineAssembly.operations());
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -954,7 +954,7 @@ bool TypeChecker::visit(InlineAssembly const& _inlineAssembly)
|
||||
// External references have already been resolved in a prior stage and stored in the annotation.
|
||||
// We run the resolve step again regardless.
|
||||
yul::ExternalIdentifierAccess::Resolver identifierAccess = [&](
|
||||
assembly::Identifier const& _identifier,
|
||||
yul::Identifier const& _identifier,
|
||||
yul::IdentifierContext _context,
|
||||
bool
|
||||
)
|
||||
@ -1039,13 +1039,13 @@ bool TypeChecker::visit(InlineAssembly const& _inlineAssembly)
|
||||
return size_t(1);
|
||||
};
|
||||
solAssert(!_inlineAssembly.annotation().analysisInfo, "");
|
||||
_inlineAssembly.annotation().analysisInfo = make_shared<assembly::AsmAnalysisInfo>();
|
||||
assembly::AsmAnalyzer analyzer(
|
||||
_inlineAssembly.annotation().analysisInfo = make_shared<yul::AsmAnalysisInfo>();
|
||||
yul::AsmAnalyzer analyzer(
|
||||
*_inlineAssembly.annotation().analysisInfo,
|
||||
m_errorReporter,
|
||||
m_evmVersion,
|
||||
Error::Type::SyntaxError,
|
||||
assembly::AsmFlavour::Loose,
|
||||
yul::AsmFlavour::Loose,
|
||||
identifierAccess
|
||||
);
|
||||
if (!analyzer.analyze(_inlineAssembly.operations()))
|
||||
|
@ -40,48 +40,48 @@ public:
|
||||
explicit AssemblyViewPureChecker(std::function<void(StateMutability, SourceLocation const&)> _reportMutability):
|
||||
m_reportMutability(_reportMutability) {}
|
||||
|
||||
void operator()(assembly::Label const&) { }
|
||||
void operator()(assembly::Instruction const& _instruction)
|
||||
void operator()(yul::Label const&) { }
|
||||
void operator()(yul::Instruction const& _instruction)
|
||||
{
|
||||
checkInstruction(_instruction.location, _instruction.instruction);
|
||||
}
|
||||
void operator()(assembly::Literal const&) {}
|
||||
void operator()(assembly::Identifier const&) {}
|
||||
void operator()(assembly::FunctionalInstruction const& _instr)
|
||||
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()(assembly::ExpressionStatement const& _expr)
|
||||
void operator()(yul::ExpressionStatement const& _expr)
|
||||
{
|
||||
boost::apply_visitor(*this, _expr.expression);
|
||||
}
|
||||
void operator()(assembly::StackAssignment const&) {}
|
||||
void operator()(assembly::Assignment const& _assignment)
|
||||
void operator()(yul::StackAssignment const&) {}
|
||||
void operator()(yul::Assignment const& _assignment)
|
||||
{
|
||||
boost::apply_visitor(*this, *_assignment.value);
|
||||
}
|
||||
void operator()(assembly::VariableDeclaration const& _varDecl)
|
||||
void operator()(yul::VariableDeclaration const& _varDecl)
|
||||
{
|
||||
if (_varDecl.value)
|
||||
boost::apply_visitor(*this, *_varDecl.value);
|
||||
}
|
||||
void operator()(assembly::FunctionDefinition const& _funDef)
|
||||
void operator()(yul::FunctionDefinition const& _funDef)
|
||||
{
|
||||
(*this)(_funDef.body);
|
||||
}
|
||||
void operator()(assembly::FunctionCall const& _funCall)
|
||||
void operator()(yul::FunctionCall const& _funCall)
|
||||
{
|
||||
for (auto const& arg: _funCall.arguments)
|
||||
boost::apply_visitor(*this, arg);
|
||||
}
|
||||
void operator()(assembly::If const& _if)
|
||||
void operator()(yul::If const& _if)
|
||||
{
|
||||
boost::apply_visitor(*this, *_if.condition);
|
||||
(*this)(_if.body);
|
||||
}
|
||||
void operator()(assembly::Switch const& _switch)
|
||||
void operator()(yul::Switch const& _switch)
|
||||
{
|
||||
boost::apply_visitor(*this, *_switch.expression);
|
||||
for (auto const& _case: _switch.cases)
|
||||
@ -91,14 +91,14 @@ public:
|
||||
(*this)(_case.body);
|
||||
}
|
||||
}
|
||||
void operator()(assembly::ForLoop const& _for)
|
||||
void operator()(yul::ForLoop const& _for)
|
||||
{
|
||||
(*this)(_for.pre);
|
||||
boost::apply_visitor(*this, *_for.condition);
|
||||
(*this)(_for.body);
|
||||
(*this)(_for.post);
|
||||
}
|
||||
void operator()(assembly::Block const& _block)
|
||||
void operator()(yul::Block const& _block)
|
||||
{
|
||||
for (auto const& s: _block.statements)
|
||||
boost::apply_visitor(*this, s);
|
||||
|
@ -41,6 +41,12 @@
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
|
||||
namespace yul
|
||||
{
|
||||
// Forward-declaration to <yul/AsmData.h>
|
||||
struct Block;
|
||||
}
|
||||
|
||||
namespace dev
|
||||
{
|
||||
namespace solidity
|
||||
@ -1028,12 +1034,6 @@ public:
|
||||
StatementAnnotation& annotation() const override;
|
||||
};
|
||||
|
||||
namespace assembly
|
||||
{
|
||||
// Forward-declaration to AsmData.h
|
||||
struct Block;
|
||||
}
|
||||
|
||||
/**
|
||||
* Inline assembly.
|
||||
*/
|
||||
@ -1043,18 +1043,18 @@ public:
|
||||
InlineAssembly(
|
||||
SourceLocation const& _location,
|
||||
ASTPointer<ASTString> const& _docString,
|
||||
std::shared_ptr<assembly::Block> const& _operations
|
||||
std::shared_ptr<yul::Block> const& _operations
|
||||
):
|
||||
Statement(_location, _docString), m_operations(_operations) {}
|
||||
void accept(ASTVisitor& _visitor) override;
|
||||
void accept(ASTConstVisitor& _visitor) const override;
|
||||
|
||||
assembly::Block const& operations() const { return *m_operations; }
|
||||
yul::Block const& operations() const { return *m_operations; }
|
||||
|
||||
InlineAssemblyAnnotation& annotation() const override;
|
||||
|
||||
private:
|
||||
std::shared_ptr<assembly::Block> m_operations;
|
||||
std::shared_ptr<yul::Block> m_operations;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -30,6 +30,12 @@
|
||||
#include <vector>
|
||||
#include <set>
|
||||
|
||||
namespace yul
|
||||
{
|
||||
struct AsmAnalysisInfo;
|
||||
struct Identifier;
|
||||
}
|
||||
|
||||
namespace dev
|
||||
{
|
||||
namespace solidity
|
||||
@ -120,12 +126,6 @@ struct StatementAnnotation: ASTAnnotation, DocumentedAnnotation
|
||||
{
|
||||
};
|
||||
|
||||
namespace assembly
|
||||
{
|
||||
struct AsmAnalysisInfo;
|
||||
struct Identifier;
|
||||
}
|
||||
|
||||
struct InlineAssemblyAnnotation: StatementAnnotation
|
||||
{
|
||||
struct ExternalIdentifierInfo
|
||||
@ -137,9 +137,9 @@ struct InlineAssemblyAnnotation: StatementAnnotation
|
||||
};
|
||||
|
||||
/// Mapping containing resolved references to external identifiers and their value size
|
||||
std::map<assembly::Identifier const*, ExternalIdentifierInfo> externalReferences;
|
||||
std::map<yul::Identifier const*, ExternalIdentifierInfo> externalReferences;
|
||||
/// Information generated during analysis phase.
|
||||
std::shared_ptr<assembly::AsmAnalysisInfo> analysisInfo;
|
||||
std::shared_ptr<yul::AsmAnalysisInfo> analysisInfo;
|
||||
};
|
||||
|
||||
struct ReturnAnnotation: StatementAnnotation
|
||||
|
@ -172,7 +172,7 @@ void ASTJsonConverter::appendExpressionAttributes(
|
||||
_attributes += exprAttributes;
|
||||
}
|
||||
|
||||
Json::Value ASTJsonConverter::inlineAssemblyIdentifierToJson(pair<assembly::Identifier const* ,InlineAssemblyAnnotation::ExternalIdentifierInfo> _info) const
|
||||
Json::Value ASTJsonConverter::inlineAssemblyIdentifierToJson(pair<yul::Identifier const* ,InlineAssemblyAnnotation::ExternalIdentifierInfo> _info) const
|
||||
{
|
||||
Json::Value tuple(Json::objectValue);
|
||||
tuple["src"] = sourceLocationToString(_info.first->location);
|
||||
@ -465,7 +465,7 @@ bool ASTJsonConverter::visit(InlineAssembly const& _node)
|
||||
}
|
||||
}
|
||||
setJsonNode(_node, "InlineAssembly", {
|
||||
make_pair("operations", Json::Value(assembly::AsmPrinter()(_node.operations()))),
|
||||
make_pair("operations", Json::Value(yul::AsmPrinter()(_node.operations()))),
|
||||
make_pair("externalReferences", std::move(externalReferences))
|
||||
});
|
||||
return false;
|
||||
|
@ -135,7 +135,7 @@ private:
|
||||
{
|
||||
return _node ? toJson(*_node) : Json::nullValue;
|
||||
}
|
||||
Json::Value inlineAssemblyIdentifierToJson(std::pair<assembly::Identifier const* , InlineAssemblyAnnotation::ExternalIdentifierInfo> _info) const;
|
||||
Json::Value inlineAssemblyIdentifierToJson(std::pair<yul::Identifier const* , InlineAssemblyAnnotation::ExternalIdentifierInfo> _info) const;
|
||||
static std::string location(VariableDeclaration::Location _location);
|
||||
static std::string contractKind(ContractDefinition::ContractKind _kind);
|
||||
static std::string functionCallKind(FunctionCallKind _kind);
|
||||
|
@ -323,7 +323,7 @@ void CompilerContext::appendInlineAssembly(
|
||||
|
||||
yul::ExternalIdentifierAccess identifierAccess;
|
||||
identifierAccess.resolve = [&](
|
||||
assembly::Identifier const& _identifier,
|
||||
yul::Identifier const& _identifier,
|
||||
yul::IdentifierContext,
|
||||
bool
|
||||
)
|
||||
@ -332,7 +332,7 @@ void CompilerContext::appendInlineAssembly(
|
||||
return it == _localVariables.end() ? size_t(-1) : 1;
|
||||
};
|
||||
identifierAccess.generateCode = [&](
|
||||
assembly::Identifier const& _identifier,
|
||||
yul::Identifier const& _identifier,
|
||||
yul::IdentifierContext _context,
|
||||
yul::AbstractAssembly& _assembly
|
||||
)
|
||||
@ -361,19 +361,19 @@ void CompilerContext::appendInlineAssembly(
|
||||
ErrorList errors;
|
||||
ErrorReporter errorReporter(errors);
|
||||
auto scanner = make_shared<langutil::Scanner>(langutil::CharStream(_assembly), "--CODEGEN--");
|
||||
auto parserResult = assembly::Parser(errorReporter, assembly::AsmFlavour::Strict).parse(scanner, false);
|
||||
auto parserResult = yul::Parser(errorReporter, yul::AsmFlavour::Strict).parse(scanner, false);
|
||||
#ifdef SOL_OUTPUT_ASM
|
||||
cout << assembly::AsmPrinter()(*parserResult) << endl;
|
||||
cout << yul::AsmPrinter()(*parserResult) << endl;
|
||||
#endif
|
||||
assembly::AsmAnalysisInfo analysisInfo;
|
||||
yul::AsmAnalysisInfo analysisInfo;
|
||||
bool analyzerResult = false;
|
||||
if (parserResult)
|
||||
analyzerResult = assembly::AsmAnalyzer(
|
||||
analyzerResult = yul::AsmAnalyzer(
|
||||
analysisInfo,
|
||||
errorReporter,
|
||||
m_evmVersion,
|
||||
boost::none,
|
||||
assembly::AsmFlavour::Strict,
|
||||
yul::AsmFlavour::Strict,
|
||||
identifierAccess.resolve
|
||||
).analyze(*parserResult);
|
||||
if (!parserResult || !errorReporter.errors().empty() || !analyzerResult)
|
||||
@ -395,7 +395,7 @@ void CompilerContext::appendInlineAssembly(
|
||||
}
|
||||
|
||||
solAssert(errorReporter.errors().empty(), "Failed to analyze inline assembly block.");
|
||||
assembly::CodeGenerator::assemble(*parserResult, analysisInfo, *m_asm, identifierAccess, _system);
|
||||
yul::CodeGenerator::assemble(*parserResult, analysisInfo, *m_asm, identifierAccess, _system);
|
||||
|
||||
// Reset the source location to the one of the node (instead of the CODEGEN source location)
|
||||
updateSourceLocation();
|
||||
|
@ -496,14 +496,14 @@ bool ContractCompiler::visit(InlineAssembly const& _inlineAssembly)
|
||||
{
|
||||
unsigned startStackHeight = m_context.stackHeight();
|
||||
yul::ExternalIdentifierAccess identifierAccess;
|
||||
identifierAccess.resolve = [&](assembly::Identifier const& _identifier, yul::IdentifierContext, bool)
|
||||
identifierAccess.resolve = [&](yul::Identifier const& _identifier, yul::IdentifierContext, bool)
|
||||
{
|
||||
auto ref = _inlineAssembly.annotation().externalReferences.find(&_identifier);
|
||||
if (ref == _inlineAssembly.annotation().externalReferences.end())
|
||||
return size_t(-1);
|
||||
return ref->second.valueSize;
|
||||
};
|
||||
identifierAccess.generateCode = [&](assembly::Identifier const& _identifier, yul::IdentifierContext _context, yul::AbstractAssembly& _assembly)
|
||||
identifierAccess.generateCode = [&](yul::Identifier const& _identifier, yul::IdentifierContext _context, yul::AbstractAssembly& _assembly)
|
||||
{
|
||||
auto ref = _inlineAssembly.annotation().externalReferences.find(&_identifier);
|
||||
solAssert(ref != _inlineAssembly.annotation().externalReferences.end(), "");
|
||||
@ -615,7 +615,7 @@ bool ContractCompiler::visit(InlineAssembly const& _inlineAssembly)
|
||||
}
|
||||
};
|
||||
solAssert(_inlineAssembly.annotation().analysisInfo, "");
|
||||
assembly::CodeGenerator::assemble(
|
||||
yul::CodeGenerator::assemble(
|
||||
_inlineAssembly.operations(),
|
||||
*_inlineAssembly.annotation().analysisInfo,
|
||||
m_context.nonConstAssembly(),
|
||||
|
@ -40,19 +40,19 @@ using namespace dev::solidity;
|
||||
|
||||
namespace
|
||||
{
|
||||
assembly::AsmFlavour languageToAsmFlavour(AssemblyStack::Language _language)
|
||||
yul::AsmFlavour languageToAsmFlavour(AssemblyStack::Language _language)
|
||||
{
|
||||
switch (_language)
|
||||
{
|
||||
case AssemblyStack::Language::Assembly:
|
||||
return assembly::AsmFlavour::Loose;
|
||||
return yul::AsmFlavour::Loose;
|
||||
case AssemblyStack::Language::StrictAssembly:
|
||||
return assembly::AsmFlavour::Strict;
|
||||
return yul::AsmFlavour::Strict;
|
||||
case AssemblyStack::Language::Yul:
|
||||
return assembly::AsmFlavour::Yul;
|
||||
return yul::AsmFlavour::Yul;
|
||||
}
|
||||
solAssert(false, "");
|
||||
return assembly::AsmFlavour::Yul;
|
||||
return yul::AsmFlavour::Yul;
|
||||
}
|
||||
|
||||
}
|
||||
@ -69,7 +69,7 @@ bool AssemblyStack::parseAndAnalyze(std::string const& _sourceName, std::string
|
||||
m_errors.clear();
|
||||
m_analysisSuccessful = false;
|
||||
m_scanner = make_shared<Scanner>(CharStream(_source), _sourceName);
|
||||
m_parserResult = assembly::Parser(m_errorReporter, languageToAsmFlavour(m_language)).parse(m_scanner, false);
|
||||
m_parserResult = yul::Parser(m_errorReporter, languageToAsmFlavour(m_language)).parse(m_scanner, false);
|
||||
if (!m_errorReporter.errors().empty())
|
||||
return false;
|
||||
solAssert(m_parserResult, "");
|
||||
@ -77,21 +77,21 @@ bool AssemblyStack::parseAndAnalyze(std::string const& _sourceName, std::string
|
||||
return analyzeParsed();
|
||||
}
|
||||
|
||||
bool AssemblyStack::analyze(assembly::Block const& _block, Scanner const* _scanner)
|
||||
bool AssemblyStack::analyze(yul::Block const& _block, Scanner const* _scanner)
|
||||
{
|
||||
m_errors.clear();
|
||||
m_analysisSuccessful = false;
|
||||
if (_scanner)
|
||||
m_scanner = make_shared<Scanner>(*_scanner);
|
||||
m_parserResult = make_shared<assembly::Block>(_block);
|
||||
m_parserResult = make_shared<yul::Block>(_block);
|
||||
|
||||
return analyzeParsed();
|
||||
}
|
||||
|
||||
bool AssemblyStack::analyzeParsed()
|
||||
{
|
||||
m_analysisInfo = make_shared<assembly::AsmAnalysisInfo>();
|
||||
assembly::AsmAnalyzer analyzer(*m_analysisInfo, m_errorReporter, m_evmVersion, boost::none, languageToAsmFlavour(m_language));
|
||||
m_analysisInfo = make_shared<yul::AsmAnalysisInfo>();
|
||||
yul::AsmAnalyzer analyzer(*m_analysisInfo, m_errorReporter, m_evmVersion, boost::none, languageToAsmFlavour(m_language));
|
||||
m_analysisSuccessful = analyzer.analyze(*m_parserResult);
|
||||
return m_analysisSuccessful;
|
||||
}
|
||||
@ -108,7 +108,7 @@ MachineAssemblyObject AssemblyStack::assemble(Machine _machine) const
|
||||
{
|
||||
MachineAssemblyObject object;
|
||||
eth::Assembly assembly;
|
||||
assembly::CodeGenerator::assemble(*m_parserResult, *m_analysisInfo, assembly);
|
||||
yul::CodeGenerator::assemble(*m_parserResult, *m_analysisInfo, assembly);
|
||||
object.bytecode = make_shared<eth::LinkerObject>(assembly.assemble());
|
||||
object.assembly = assembly.assemblyString();
|
||||
return object;
|
||||
@ -132,5 +132,5 @@ MachineAssemblyObject AssemblyStack::assemble(Machine _machine) const
|
||||
string AssemblyStack::print() const
|
||||
{
|
||||
solAssert(m_parserResult, "");
|
||||
return assembly::AsmPrinter(m_language == Language::Yul)(*m_parserResult);
|
||||
return yul::AsmPrinter(m_language == Language::Yul)(*m_parserResult);
|
||||
}
|
||||
|
@ -34,16 +34,17 @@ namespace langutil
|
||||
class Scanner;
|
||||
}
|
||||
|
||||
namespace dev
|
||||
{
|
||||
namespace solidity
|
||||
{
|
||||
namespace assembly
|
||||
namespace yul
|
||||
{
|
||||
struct AsmAnalysisInfo;
|
||||
struct Block;
|
||||
}
|
||||
|
||||
namespace dev
|
||||
{
|
||||
namespace solidity
|
||||
{
|
||||
|
||||
struct MachineAssemblyObject
|
||||
{
|
||||
std::shared_ptr<eth::LinkerObject> bytecode;
|
||||
@ -73,7 +74,7 @@ public:
|
||||
|
||||
/// Runs analysis step on the supplied block, returns false if input cannot be assembled.
|
||||
/// Multiple calls overwrite the previous state.
|
||||
bool analyze(assembly::Block const& _block, langutil::Scanner const* _scanner = nullptr);
|
||||
bool analyze(yul::Block const& _block, langutil::Scanner const* _scanner = nullptr);
|
||||
|
||||
/// Run the assembly step (should only be called after parseAndAnalyze).
|
||||
MachineAssemblyObject assemble(Machine _machine) const;
|
||||
@ -93,8 +94,8 @@ private:
|
||||
std::shared_ptr<langutil::Scanner> m_scanner;
|
||||
|
||||
bool m_analysisSuccessful = false;
|
||||
std::shared_ptr<assembly::Block> m_parserResult;
|
||||
std::shared_ptr<assembly::AsmAnalysisInfo> m_analysisInfo;
|
||||
std::shared_ptr<yul::Block> m_parserResult;
|
||||
std::shared_ptr<yul::AsmAnalysisInfo> m_analysisInfo;
|
||||
langutil::ErrorList m_errors;
|
||||
langutil::ErrorReporter m_errorReporter;
|
||||
};
|
||||
|
@ -1012,8 +1012,8 @@ ASTPointer<InlineAssembly> Parser::parseInlineAssembly(ASTPointer<ASTString> con
|
||||
m_scanner->next();
|
||||
}
|
||||
|
||||
assembly::Parser asmParser(m_errorReporter);
|
||||
shared_ptr<assembly::Block> block = asmParser.parse(m_scanner, true);
|
||||
yul::Parser asmParser(m_errorReporter);
|
||||
shared_ptr<yul::Block> block = asmParser.parse(m_scanner, true);
|
||||
nodeFactory.markEndPosition();
|
||||
return nodeFactory.createNode<InlineAssembly>(_docString, block);
|
||||
}
|
||||
|
@ -23,33 +23,3 @@
|
||||
|
||||
#include <libyul/AsmDataForward.h>
|
||||
|
||||
namespace dev
|
||||
{
|
||||
namespace yul
|
||||
{
|
||||
|
||||
using Instruction = solidity::assembly::Instruction;
|
||||
using Literal = solidity::assembly::Literal;
|
||||
using Label = solidity::assembly::Label;
|
||||
using StackAssignment = solidity::assembly::StackAssignment;
|
||||
using Identifier = solidity::assembly::Identifier;
|
||||
using Assignment = solidity::assembly::Assignment;
|
||||
using VariableDeclaration = solidity::assembly::VariableDeclaration;
|
||||
using FunctionalInstruction = solidity::assembly::FunctionalInstruction;
|
||||
using FunctionDefinition = solidity::assembly::FunctionDefinition;
|
||||
using FunctionCall = solidity::assembly::FunctionCall;
|
||||
using If = solidity::assembly::If;
|
||||
using Case = solidity::assembly::Case;
|
||||
using Switch = solidity::assembly::Switch;
|
||||
using ForLoop = solidity::assembly::ForLoop;
|
||||
using ExpressionStatement = solidity::assembly::ExpressionStatement;
|
||||
using Block = solidity::assembly::Block;
|
||||
|
||||
using TypedName = solidity::assembly::TypedName;
|
||||
class YulString;
|
||||
|
||||
using Expression = boost::variant<FunctionalInstruction, FunctionCall, Identifier, Literal>;
|
||||
using Statement = boost::variant<ExpressionStatement, Instruction, Label, StackAssignment, Assignment, VariableDeclaration, FunctionDefinition, If, Switch, ForLoop, Block>;
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -36,8 +36,9 @@
|
||||
using namespace std;
|
||||
using namespace dev;
|
||||
using namespace langutil;
|
||||
using namespace yul;
|
||||
using namespace dev;
|
||||
using namespace dev::solidity;
|
||||
using namespace dev::solidity::assembly;
|
||||
|
||||
namespace {
|
||||
|
||||
@ -65,7 +66,7 @@ bool AsmAnalyzer::operator()(Label const& _label)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AsmAnalyzer::operator()(assembly::Instruction const& _instruction)
|
||||
bool AsmAnalyzer::operator()(yul::Instruction const& _instruction)
|
||||
{
|
||||
checkLooseFeature(
|
||||
_instruction.location,
|
||||
@ -78,11 +79,11 @@ bool AsmAnalyzer::operator()(assembly::Instruction const& _instruction)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AsmAnalyzer::operator()(assembly::Literal const& _literal)
|
||||
bool AsmAnalyzer::operator()(Literal const& _literal)
|
||||
{
|
||||
expectValidType(_literal.type.str(), _literal.location);
|
||||
++m_stackHeight;
|
||||
if (_literal.kind == assembly::LiteralKind::String && _literal.value.str().size() > 32)
|
||||
if (_literal.kind == LiteralKind::String && _literal.value.str().size() > 32)
|
||||
{
|
||||
m_errorReporter.typeError(
|
||||
_literal.location,
|
||||
@ -90,7 +91,7 @@ bool AsmAnalyzer::operator()(assembly::Literal const& _literal)
|
||||
);
|
||||
return false;
|
||||
}
|
||||
else if (_literal.kind == assembly::LiteralKind::Number && bigint(_literal.value.str()) > u256(-1))
|
||||
else if (_literal.kind == LiteralKind::Number && bigint(_literal.value.str()) > u256(-1))
|
||||
{
|
||||
m_errorReporter.typeError(
|
||||
_literal.location,
|
||||
@ -98,7 +99,7 @@ bool AsmAnalyzer::operator()(assembly::Literal const& _literal)
|
||||
);
|
||||
return false;
|
||||
}
|
||||
else if (_literal.kind == assembly::LiteralKind::Boolean)
|
||||
else if (_literal.kind == LiteralKind::Boolean)
|
||||
{
|
||||
solAssert(m_flavour == AsmFlavour::Yul, "");
|
||||
solAssert(_literal.value == YulString{string("true")} || _literal.value == YulString{string("false")}, "");
|
||||
@ -107,7 +108,7 @@ bool AsmAnalyzer::operator()(assembly::Literal const& _literal)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AsmAnalyzer::operator()(assembly::Identifier const& _identifier)
|
||||
bool AsmAnalyzer::operator()(Identifier const& _identifier)
|
||||
{
|
||||
solAssert(!_identifier.name.empty(), "");
|
||||
size_t numErrorsBefore = m_errorReporter.errors().size();
|
||||
@ -177,7 +178,7 @@ bool AsmAnalyzer::operator()(FunctionalInstruction const& _instr)
|
||||
return success;
|
||||
}
|
||||
|
||||
bool AsmAnalyzer::operator()(assembly::ExpressionStatement const& _statement)
|
||||
bool AsmAnalyzer::operator()(ExpressionStatement const& _statement)
|
||||
{
|
||||
int initialStackHeight = m_stackHeight;
|
||||
bool success = boost::apply_visitor(*this, _statement.expression);
|
||||
@ -198,7 +199,7 @@ bool AsmAnalyzer::operator()(assembly::ExpressionStatement const& _statement)
|
||||
return success;
|
||||
}
|
||||
|
||||
bool AsmAnalyzer::operator()(assembly::StackAssignment const& _assignment)
|
||||
bool AsmAnalyzer::operator()(StackAssignment const& _assignment)
|
||||
{
|
||||
checkLooseFeature(
|
||||
_assignment.location,
|
||||
@ -209,7 +210,7 @@ bool AsmAnalyzer::operator()(assembly::StackAssignment const& _assignment)
|
||||
return success;
|
||||
}
|
||||
|
||||
bool AsmAnalyzer::operator()(assembly::Assignment const& _assignment)
|
||||
bool AsmAnalyzer::operator()(Assignment const& _assignment)
|
||||
{
|
||||
solAssert(_assignment.value, "");
|
||||
int const expectedItems = _assignment.variableNames.size();
|
||||
@ -235,7 +236,7 @@ bool AsmAnalyzer::operator()(assembly::Assignment const& _assignment)
|
||||
return success;
|
||||
}
|
||||
|
||||
bool AsmAnalyzer::operator()(assembly::VariableDeclaration const& _varDecl)
|
||||
bool AsmAnalyzer::operator()(VariableDeclaration const& _varDecl)
|
||||
{
|
||||
bool success = true;
|
||||
int const numVariables = _varDecl.variables.size();
|
||||
@ -261,7 +262,7 @@ bool AsmAnalyzer::operator()(assembly::VariableDeclaration const& _varDecl)
|
||||
return success;
|
||||
}
|
||||
|
||||
bool AsmAnalyzer::operator()(assembly::FunctionDefinition const& _funDef)
|
||||
bool AsmAnalyzer::operator()(FunctionDefinition const& _funDef)
|
||||
{
|
||||
solAssert(!_funDef.name.empty(), "");
|
||||
Block const* virtualBlock = m_info.virtualBlocks.at(&_funDef).get();
|
||||
@ -283,7 +284,7 @@ bool AsmAnalyzer::operator()(assembly::FunctionDefinition const& _funDef)
|
||||
return success;
|
||||
}
|
||||
|
||||
bool AsmAnalyzer::operator()(assembly::FunctionCall const& _funCall)
|
||||
bool AsmAnalyzer::operator()(FunctionCall const& _funCall)
|
||||
{
|
||||
solAssert(!_funCall.functionName.name.empty(), "");
|
||||
bool success = true;
|
||||
@ -397,7 +398,7 @@ bool AsmAnalyzer::operator()(Switch const& _switch)
|
||||
return success;
|
||||
}
|
||||
|
||||
bool AsmAnalyzer::operator()(assembly::ForLoop const& _for)
|
||||
bool AsmAnalyzer::operator()(ForLoop const& _for)
|
||||
{
|
||||
solAssert(_for.condition, "");
|
||||
|
||||
@ -486,7 +487,7 @@ bool AsmAnalyzer::expectDeposit(int _deposit, int _oldHeight, SourceLocation con
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AsmAnalyzer::checkAssignment(assembly::Identifier const& _variable, size_t _valueSize)
|
||||
bool AsmAnalyzer::checkAssignment(Identifier const& _variable, size_t _valueSize)
|
||||
{
|
||||
solAssert(!_variable.name.empty(), "");
|
||||
bool success = true;
|
||||
|
@ -41,11 +41,7 @@ class ErrorReporter;
|
||||
struct SourceLocation;
|
||||
}
|
||||
|
||||
namespace dev
|
||||
{
|
||||
namespace solidity
|
||||
{
|
||||
namespace assembly
|
||||
namespace yul
|
||||
{
|
||||
|
||||
struct AsmAnalysisInfo;
|
||||
@ -61,10 +57,10 @@ public:
|
||||
explicit AsmAnalyzer(
|
||||
AsmAnalysisInfo& _analysisInfo,
|
||||
langutil::ErrorReporter& _errorReporter,
|
||||
EVMVersion _evmVersion,
|
||||
dev::solidity::EVMVersion _evmVersion,
|
||||
boost::optional<langutil::Error::Type> _errorTypeForLoose,
|
||||
AsmFlavour _flavour = AsmFlavour::Loose,
|
||||
yul::ExternalIdentifierAccess::Resolver const& _resolver = yul::ExternalIdentifierAccess::Resolver()
|
||||
ExternalIdentifierAccess::Resolver const& _resolver = ExternalIdentifierAccess::Resolver()
|
||||
):
|
||||
m_resolver(_resolver),
|
||||
m_info(_analysisInfo),
|
||||
@ -74,23 +70,23 @@ public:
|
||||
m_errorTypeForLoose(_errorTypeForLoose)
|
||||
{}
|
||||
|
||||
bool analyze(assembly::Block const& _block);
|
||||
bool analyze(Block const& _block);
|
||||
|
||||
bool operator()(assembly::Instruction const&);
|
||||
bool operator()(assembly::Literal const& _literal);
|
||||
bool operator()(assembly::Identifier const&);
|
||||
bool operator()(assembly::FunctionalInstruction const& _functionalInstruction);
|
||||
bool operator()(assembly::Label const& _label);
|
||||
bool operator()(assembly::ExpressionStatement const&);
|
||||
bool operator()(assembly::StackAssignment const&);
|
||||
bool operator()(assembly::Assignment const& _assignment);
|
||||
bool operator()(assembly::VariableDeclaration const& _variableDeclaration);
|
||||
bool operator()(assembly::FunctionDefinition const& _functionDefinition);
|
||||
bool operator()(assembly::FunctionCall const& _functionCall);
|
||||
bool operator()(assembly::If const& _if);
|
||||
bool operator()(assembly::Switch const& _switch);
|
||||
bool operator()(assembly::ForLoop const& _forLoop);
|
||||
bool operator()(assembly::Block const& _block);
|
||||
bool operator()(Instruction const&);
|
||||
bool operator()(Literal const& _literal);
|
||||
bool operator()(Identifier const&);
|
||||
bool operator()(FunctionalInstruction const& _functionalInstruction);
|
||||
bool operator()(Label const& _label);
|
||||
bool operator()(ExpressionStatement const&);
|
||||
bool operator()(StackAssignment const&);
|
||||
bool operator()(Assignment const& _assignment);
|
||||
bool operator()(VariableDeclaration const& _variableDeclaration);
|
||||
bool operator()(FunctionDefinition const& _functionDefinition);
|
||||
bool operator()(FunctionCall const& _functionCall);
|
||||
bool operator()(If const& _if);
|
||||
bool operator()(Switch const& _switch);
|
||||
bool operator()(ForLoop const& _forLoop);
|
||||
bool operator()(Block const& _block);
|
||||
|
||||
private:
|
||||
/// Visits the statement and expects it to deposit one item onto the stack.
|
||||
@ -99,11 +95,11 @@ private:
|
||||
|
||||
/// Verifies that a variable to be assigned to exists and has the same size
|
||||
/// as the value, @a _valueSize, unless that is equal to -1.
|
||||
bool checkAssignment(assembly::Identifier const& _assignment, size_t _valueSize = size_t(-1));
|
||||
bool checkAssignment(Identifier const& _assignment, size_t _valueSize = size_t(-1));
|
||||
|
||||
Scope& scope(assembly::Block const* _block);
|
||||
Scope& scope(Block const* _block);
|
||||
void expectValidType(std::string const& type, langutil::SourceLocation const& _location);
|
||||
void warnOnInstructions(solidity::Instruction _instr, langutil::SourceLocation const& _location);
|
||||
void warnOnInstructions(dev::solidity::Instruction _instr, langutil::SourceLocation const& _location);
|
||||
|
||||
/// Depending on @a m_flavour and @a m_errorTypeForLoose, throws an internal compiler
|
||||
/// exception (if the flavour is not Loose), reports an error/warning
|
||||
@ -118,11 +114,9 @@ private:
|
||||
std::set<Scope::Variable const*> m_activeVariables;
|
||||
AsmAnalysisInfo& m_info;
|
||||
langutil::ErrorReporter& m_errorReporter;
|
||||
EVMVersion m_evmVersion;
|
||||
dev::solidity::EVMVersion m_evmVersion;
|
||||
AsmFlavour m_flavour = AsmFlavour::Loose;
|
||||
boost::optional<langutil::Error::Type> m_errorTypeForLoose;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -28,11 +28,7 @@
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
namespace dev
|
||||
{
|
||||
namespace solidity
|
||||
{
|
||||
namespace assembly
|
||||
namespace yul
|
||||
{
|
||||
|
||||
struct Scope;
|
||||
@ -40,13 +36,11 @@ struct Scope;
|
||||
struct AsmAnalysisInfo
|
||||
{
|
||||
using StackHeightInfo = std::map<void const*, int>;
|
||||
using Scopes = std::map<assembly::Block const*, std::shared_ptr<Scope>>;
|
||||
using Scopes = std::map<Block const*, std::shared_ptr<Scope>>;
|
||||
Scopes scopes;
|
||||
StackHeightInfo stackHeightInfo;
|
||||
/// Virtual blocks which will be used for scopes for function arguments and return values.
|
||||
std::map<FunctionDefinition const*, std::shared_ptr<assembly::Block const>> virtualBlocks;
|
||||
std::map<FunctionDefinition const*, std::shared_ptr<Block const>> virtualBlocks;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -48,10 +48,10 @@
|
||||
using namespace std;
|
||||
using namespace dev;
|
||||
using namespace langutil;
|
||||
using namespace yul;
|
||||
using namespace dev::solidity;
|
||||
using namespace dev::solidity::assembly;
|
||||
|
||||
class EthAssemblyAdapter: public yul::AbstractAssembly
|
||||
class EthAssemblyAdapter: public AbstractAssembly
|
||||
{
|
||||
public:
|
||||
explicit EthAssemblyAdapter(eth::Assembly& _assembly):
|
||||
@ -143,16 +143,16 @@ private:
|
||||
eth::Assembly& m_assembly;
|
||||
};
|
||||
|
||||
void assembly::CodeGenerator::assemble(
|
||||
void CodeGenerator::assemble(
|
||||
Block const& _parsedData,
|
||||
AsmAnalysisInfo& _analysisInfo,
|
||||
eth::Assembly& _assembly,
|
||||
yul::ExternalIdentifierAccess const& _identifierAccess,
|
||||
ExternalIdentifierAccess const& _identifierAccess,
|
||||
bool _useNamedLabelsForFunctions
|
||||
)
|
||||
{
|
||||
EthAssemblyAdapter assemblyAdapter(_assembly);
|
||||
yul::CodeTransform(
|
||||
CodeTransform(
|
||||
assemblyAdapter,
|
||||
_analysisInfo,
|
||||
false,
|
||||
|
@ -32,9 +32,9 @@ namespace eth
|
||||
{
|
||||
class Assembly;
|
||||
}
|
||||
namespace solidity
|
||||
{
|
||||
namespace assembly
|
||||
}
|
||||
|
||||
namespace yul
|
||||
{
|
||||
struct Block;
|
||||
|
||||
@ -45,12 +45,10 @@ public:
|
||||
static void assemble(
|
||||
Block const& _parsedData,
|
||||
AsmAnalysisInfo& _analysisInfo,
|
||||
eth::Assembly& _assembly,
|
||||
dev::eth::Assembly& _assembly,
|
||||
yul::ExternalIdentifierAccess const& _identifierAccess = yul::ExternalIdentifierAccess(),
|
||||
bool _useNamedLabelsForFunctions = false
|
||||
);
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -23,7 +23,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <libyul/AsmDataForward.h>
|
||||
|
||||
#include <libyul/YulString.h>
|
||||
|
||||
#include <libevmasm/Instruction.h>
|
||||
@ -35,21 +34,16 @@
|
||||
#include <map>
|
||||
#include <memory>
|
||||
|
||||
namespace dev
|
||||
{
|
||||
namespace solidity
|
||||
{
|
||||
namespace assembly
|
||||
namespace yul
|
||||
{
|
||||
|
||||
using YulString = dev::yul::YulString;
|
||||
using Type = YulString;
|
||||
|
||||
struct TypedName { langutil::SourceLocation location; YulString name; Type type; };
|
||||
using TypedNameList = std::vector<TypedName>;
|
||||
|
||||
/// Direct EVM instruction (except PUSHi and JUMPDEST)
|
||||
struct Instruction { langutil::SourceLocation location; solidity::Instruction instruction; };
|
||||
struct Instruction { langutil::SourceLocation location; dev::solidity::Instruction instruction; };
|
||||
/// Literal number or string (up to 32 bytes)
|
||||
enum class LiteralKind { Number, Boolean, String };
|
||||
struct Literal { langutil::SourceLocation location; LiteralKind kind; YulString value; Type type; };
|
||||
@ -67,7 +61,7 @@ struct StackAssignment { langutil::SourceLocation location; Identifier variableN
|
||||
/// the same amount of items as the number of variables.
|
||||
struct Assignment { langutil::SourceLocation location; std::vector<Identifier> variableNames; std::shared_ptr<Expression> value; };
|
||||
/// Functional instruction, e.g. "mul(mload(20:u256), add(2:u256, x))"
|
||||
struct FunctionalInstruction { langutil::SourceLocation location; solidity::Instruction instruction; std::vector<Expression> arguments; };
|
||||
struct FunctionalInstruction { langutil::SourceLocation location; dev::solidity::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; };
|
||||
@ -100,5 +94,3 @@ template <class T> inline langutil::SourceLocation locationOf(T const& _node)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -24,11 +24,7 @@
|
||||
|
||||
#include <boost/variant.hpp>
|
||||
|
||||
namespace dev
|
||||
{
|
||||
namespace solidity
|
||||
{
|
||||
namespace assembly
|
||||
namespace yul
|
||||
{
|
||||
|
||||
struct Instruction;
|
||||
@ -61,5 +57,3 @@ enum class AsmFlavour
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -32,10 +32,10 @@
|
||||
using namespace std;
|
||||
using namespace dev;
|
||||
using namespace langutil;
|
||||
using namespace yul;
|
||||
using namespace dev::solidity;
|
||||
using namespace dev::solidity::assembly;
|
||||
|
||||
shared_ptr<assembly::Block> Parser::parse(std::shared_ptr<Scanner> const& _scanner, bool _reuseScanner)
|
||||
shared_ptr<Block> Parser::parse(std::shared_ptr<Scanner> const& _scanner, bool _reuseScanner)
|
||||
{
|
||||
m_recursionDepth = 0;
|
||||
try
|
||||
@ -54,10 +54,10 @@ shared_ptr<assembly::Block> Parser::parse(std::shared_ptr<Scanner> const& _scann
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
assembly::Block Parser::parseBlock()
|
||||
Block Parser::parseBlock()
|
||||
{
|
||||
RecursionGuard recursionGuard(*this);
|
||||
assembly::Block block = createWithLocation<Block>();
|
||||
Block block = createWithLocation<Block>();
|
||||
expectToken(Token::LBrace);
|
||||
while (currentToken() != Token::RBrace)
|
||||
block.statements.emplace_back(parseStatement());
|
||||
@ -66,7 +66,7 @@ assembly::Block Parser::parseBlock()
|
||||
return block;
|
||||
}
|
||||
|
||||
assembly::Statement Parser::parseStatement()
|
||||
Statement Parser::parseStatement()
|
||||
{
|
||||
RecursionGuard recursionGuard(*this);
|
||||
switch (currentToken())
|
||||
@ -79,7 +79,7 @@ assembly::Statement Parser::parseStatement()
|
||||
return parseBlock();
|
||||
case Token::If:
|
||||
{
|
||||
assembly::If _if = createWithLocation<assembly::If>();
|
||||
If _if = createWithLocation<If>();
|
||||
m_scanner->next();
|
||||
_if.condition = make_shared<Expression>(parseExpression());
|
||||
_if.body = parseBlock();
|
||||
@ -87,7 +87,7 @@ assembly::Statement Parser::parseStatement()
|
||||
}
|
||||
case Token::Switch:
|
||||
{
|
||||
assembly::Switch _switch = createWithLocation<assembly::Switch>();
|
||||
Switch _switch = createWithLocation<Switch>();
|
||||
m_scanner->next();
|
||||
_switch.expression = make_shared<Expression>(parseExpression());
|
||||
while (m_scanner->currentToken() == Token::Case)
|
||||
@ -109,7 +109,7 @@ assembly::Statement Parser::parseStatement()
|
||||
{
|
||||
if (m_flavour != AsmFlavour::Loose)
|
||||
break;
|
||||
assembly::StackAssignment assignment = createWithLocation<assembly::StackAssignment>();
|
||||
StackAssignment assignment = createWithLocation<StackAssignment>();
|
||||
advance();
|
||||
expectToken(Token::Colon);
|
||||
assignment.variableName.location = location();
|
||||
@ -139,9 +139,9 @@ assembly::Statement Parser::parseStatement()
|
||||
{
|
||||
// if a comma follows, a multiple assignment is assumed
|
||||
|
||||
if (elementary.type() != typeid(assembly::Identifier))
|
||||
if (elementary.type() != typeid(Identifier))
|
||||
fatalParserError("Label name / variable name must precede \",\" (multiple assignment).");
|
||||
assembly::Identifier const& identifier = boost::get<assembly::Identifier>(elementary);
|
||||
Identifier const& identifier = boost::get<Identifier>(elementary);
|
||||
|
||||
Assignment assignment = createWithLocation<Assignment>(identifier.location);
|
||||
assignment.variableNames.emplace_back(identifier);
|
||||
@ -150,9 +150,9 @@ assembly::Statement Parser::parseStatement()
|
||||
{
|
||||
expectToken(Token::Comma);
|
||||
elementary = parseElementaryOperation();
|
||||
if (elementary.type() != typeid(assembly::Identifier))
|
||||
if (elementary.type() != typeid(Identifier))
|
||||
fatalParserError("Variable name expected in multiple assignment.");
|
||||
assignment.variableNames.emplace_back(boost::get<assembly::Identifier>(elementary));
|
||||
assignment.variableNames.emplace_back(boost::get<Identifier>(elementary));
|
||||
}
|
||||
while (currentToken() == Token::Comma);
|
||||
|
||||
@ -165,15 +165,15 @@ assembly::Statement Parser::parseStatement()
|
||||
}
|
||||
case Token::Colon:
|
||||
{
|
||||
if (elementary.type() != typeid(assembly::Identifier))
|
||||
if (elementary.type() != typeid(Identifier))
|
||||
fatalParserError("Label name / variable name must precede \":\".");
|
||||
assembly::Identifier const& identifier = boost::get<assembly::Identifier>(elementary);
|
||||
Identifier const& identifier = boost::get<Identifier>(elementary);
|
||||
advance();
|
||||
// identifier:=: should be parsed as identifier: =: (i.e. a label),
|
||||
// while identifier:= (being followed by a non-colon) as identifier := (assignment).
|
||||
if (currentToken() == Token::Assign && peekNextToken() != Token::Colon)
|
||||
{
|
||||
assembly::Assignment assignment = createWithLocation<assembly::Assignment>(identifier.location);
|
||||
Assignment assignment = createWithLocation<Assignment>(identifier.location);
|
||||
if (m_flavour != AsmFlavour::Yul && instructions().count(identifier.name.str()))
|
||||
fatalParserError("Cannot use instruction names for identifier names.");
|
||||
advance();
|
||||
@ -197,36 +197,36 @@ assembly::Statement Parser::parseStatement()
|
||||
fatalParserError("Call or assignment expected.");
|
||||
break;
|
||||
}
|
||||
if (elementary.type() == typeid(assembly::Identifier))
|
||||
if (elementary.type() == typeid(Identifier))
|
||||
{
|
||||
Expression expr = boost::get<assembly::Identifier>(elementary);
|
||||
Expression expr = boost::get<Identifier>(elementary);
|
||||
return ExpressionStatement{locationOf(expr), expr};
|
||||
}
|
||||
else if (elementary.type() == typeid(assembly::Literal))
|
||||
else if (elementary.type() == typeid(Literal))
|
||||
{
|
||||
Expression expr = boost::get<assembly::Literal>(elementary);
|
||||
Expression expr = boost::get<Literal>(elementary);
|
||||
return ExpressionStatement{locationOf(expr), expr};
|
||||
}
|
||||
else
|
||||
{
|
||||
solAssert(elementary.type() == typeid(assembly::Instruction), "Invalid elementary operation.");
|
||||
return boost::get<assembly::Instruction>(elementary);
|
||||
solAssert(elementary.type() == typeid(Instruction), "Invalid elementary operation.");
|
||||
return boost::get<Instruction>(elementary);
|
||||
}
|
||||
}
|
||||
|
||||
assembly::Case Parser::parseCase()
|
||||
Case Parser::parseCase()
|
||||
{
|
||||
RecursionGuard recursionGuard(*this);
|
||||
assembly::Case _case = createWithLocation<assembly::Case>();
|
||||
Case _case = createWithLocation<Case>();
|
||||
if (m_scanner->currentToken() == Token::Default)
|
||||
m_scanner->next();
|
||||
else if (m_scanner->currentToken() == Token::Case)
|
||||
{
|
||||
m_scanner->next();
|
||||
ElementaryOperation literal = parseElementaryOperation();
|
||||
if (literal.type() != typeid(assembly::Literal))
|
||||
if (literal.type() != typeid(Literal))
|
||||
fatalParserError("Literal expected.");
|
||||
_case.value = make_shared<Literal>(boost::get<assembly::Literal>(std::move(literal)));
|
||||
_case.value = make_shared<Literal>(boost::get<Literal>(std::move(literal)));
|
||||
}
|
||||
else
|
||||
fatalParserError("Case or default case expected.");
|
||||
@ -235,7 +235,7 @@ assembly::Case Parser::parseCase()
|
||||
return _case;
|
||||
}
|
||||
|
||||
assembly::ForLoop Parser::parseForLoop()
|
||||
ForLoop Parser::parseForLoop()
|
||||
{
|
||||
RecursionGuard recursionGuard(*this);
|
||||
ForLoop forLoop = createWithLocation<ForLoop>();
|
||||
@ -248,7 +248,7 @@ assembly::ForLoop Parser::parseForLoop()
|
||||
return forLoop;
|
||||
}
|
||||
|
||||
assembly::Expression Parser::parseExpression()
|
||||
Expression Parser::parseExpression()
|
||||
{
|
||||
RecursionGuard recursionGuard(*this);
|
||||
// In strict mode, this might parse a plain Instruction, but
|
||||
@ -293,12 +293,12 @@ assembly::Expression Parser::parseExpression()
|
||||
Instruction& instr = boost::get<Instruction>(operation);
|
||||
return FunctionalInstruction{std::move(instr.location), instr.instruction, {}};
|
||||
}
|
||||
else if (operation.type() == typeid(assembly::Identifier))
|
||||
return boost::get<assembly::Identifier>(operation);
|
||||
else if (operation.type() == typeid(Identifier))
|
||||
return boost::get<Identifier>(operation);
|
||||
else
|
||||
{
|
||||
solAssert(operation.type() == typeid(assembly::Literal), "");
|
||||
return boost::get<assembly::Literal>(operation);
|
||||
solAssert(operation.type() == typeid(Literal), "");
|
||||
return boost::get<Literal>(operation);
|
||||
}
|
||||
}
|
||||
|
||||
@ -420,7 +420,7 @@ Parser::ElementaryOperation Parser::parseElementaryOperation()
|
||||
return ret;
|
||||
}
|
||||
|
||||
assembly::VariableDeclaration Parser::parseVariableDeclaration()
|
||||
VariableDeclaration Parser::parseVariableDeclaration()
|
||||
{
|
||||
RecursionGuard recursionGuard(*this);
|
||||
VariableDeclaration varDecl = createWithLocation<VariableDeclaration>();
|
||||
@ -445,7 +445,7 @@ assembly::VariableDeclaration Parser::parseVariableDeclaration()
|
||||
return varDecl;
|
||||
}
|
||||
|
||||
assembly::FunctionDefinition Parser::parseFunctionDefinition()
|
||||
FunctionDefinition Parser::parseFunctionDefinition()
|
||||
{
|
||||
RecursionGuard recursionGuard(*this);
|
||||
FunctionDefinition funDef = createWithLocation<FunctionDefinition>();
|
||||
@ -477,7 +477,7 @@ assembly::FunctionDefinition Parser::parseFunctionDefinition()
|
||||
return funDef;
|
||||
}
|
||||
|
||||
assembly::Expression Parser::parseCall(Parser::ElementaryOperation&& _initialOp)
|
||||
Expression Parser::parseCall(Parser::ElementaryOperation&& _initialOp)
|
||||
{
|
||||
RecursionGuard recursionGuard(*this);
|
||||
if (_initialOp.type() == typeid(Instruction))
|
||||
|
@ -29,11 +29,7 @@
|
||||
#include <liblangutil/Scanner.h>
|
||||
#include <liblangutil/ParserBase.h>
|
||||
|
||||
namespace dev
|
||||
{
|
||||
namespace solidity
|
||||
{
|
||||
namespace assembly
|
||||
namespace yul
|
||||
{
|
||||
|
||||
class Parser: public langutil::ParserBase
|
||||
@ -48,7 +44,7 @@ public:
|
||||
std::shared_ptr<Block> parse(std::shared_ptr<langutil::Scanner> const& _scanner, bool _reuseScanner);
|
||||
|
||||
protected:
|
||||
using ElementaryOperation = boost::variant<assembly::Instruction, assembly::Literal, assembly::Identifier>;
|
||||
using ElementaryOperation = boost::variant<Instruction, Literal, Identifier>;
|
||||
|
||||
/// Creates an inline assembly node with the given source location.
|
||||
template <class T> T createWithLocation(langutil::SourceLocation const& _loc = {}) const
|
||||
@ -71,7 +67,7 @@ protected:
|
||||
Case parseCase();
|
||||
ForLoop parseForLoop();
|
||||
/// Parses a functional expression that has to push exactly one stack element
|
||||
assembly::Expression parseExpression();
|
||||
Expression parseExpression();
|
||||
static std::map<std::string, dev::solidity::Instruction> const& instructions();
|
||||
static std::map<dev::solidity::Instruction, std::string> const& instructionNames();
|
||||
/// Parses an elementary operation, i.e. a literal, identifier or instruction.
|
||||
@ -80,7 +76,7 @@ protected:
|
||||
ElementaryOperation parseElementaryOperation();
|
||||
VariableDeclaration parseVariableDeclaration();
|
||||
FunctionDefinition parseFunctionDefinition();
|
||||
assembly::Expression parseCall(ElementaryOperation&& _initialOp);
|
||||
Expression parseCall(ElementaryOperation&& _initialOp);
|
||||
TypedName parseTypedName();
|
||||
std::string expectAsmIdentifier();
|
||||
|
||||
@ -91,5 +87,3 @@ private:
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -35,19 +35,19 @@
|
||||
|
||||
using namespace std;
|
||||
using namespace dev;
|
||||
using namespace yul;
|
||||
using namespace dev::solidity;
|
||||
using namespace dev::solidity::assembly;
|
||||
|
||||
//@TODO source locations
|
||||
|
||||
string AsmPrinter::operator()(assembly::Instruction const& _instruction)
|
||||
string AsmPrinter::operator()(yul::Instruction const& _instruction)
|
||||
{
|
||||
solAssert(!m_yul, "");
|
||||
solAssert(isValidInstruction(_instruction.instruction), "Invalid instruction");
|
||||
return boost::to_lower_copy(instructionInfo(_instruction.instruction).name);
|
||||
}
|
||||
|
||||
string AsmPrinter::operator()(assembly::Literal const& _literal)
|
||||
string AsmPrinter::operator()(Literal const& _literal)
|
||||
{
|
||||
switch (_literal.kind)
|
||||
{
|
||||
@ -90,13 +90,13 @@ string AsmPrinter::operator()(assembly::Literal const& _literal)
|
||||
return "\"" + out + "\"" + appendTypeName(_literal.type);
|
||||
}
|
||||
|
||||
string AsmPrinter::operator()(assembly::Identifier const& _identifier)
|
||||
string AsmPrinter::operator()(Identifier const& _identifier)
|
||||
{
|
||||
solAssert(!_identifier.name.empty(), "Invalid identifier.");
|
||||
return _identifier.name.str();
|
||||
}
|
||||
|
||||
string AsmPrinter::operator()(assembly::FunctionalInstruction const& _functionalInstruction)
|
||||
string AsmPrinter::operator()(FunctionalInstruction const& _functionalInstruction)
|
||||
{
|
||||
solAssert(!m_yul, "");
|
||||
solAssert(isValidInstruction(_functionalInstruction.instruction), "Invalid instruction");
|
||||
@ -114,21 +114,21 @@ string AsmPrinter::operator()(ExpressionStatement const& _statement)
|
||||
return boost::apply_visitor(*this, _statement.expression);
|
||||
}
|
||||
|
||||
string AsmPrinter::operator()(assembly::Label const& _label)
|
||||
string AsmPrinter::operator()(Label const& _label)
|
||||
{
|
||||
solAssert(!m_yul, "");
|
||||
solAssert(!_label.name.empty(), "Invalid label.");
|
||||
return _label.name.str() + ":";
|
||||
}
|
||||
|
||||
string AsmPrinter::operator()(assembly::StackAssignment const& _assignment)
|
||||
string AsmPrinter::operator()(StackAssignment const& _assignment)
|
||||
{
|
||||
solAssert(!m_yul, "");
|
||||
solAssert(!_assignment.variableName.name.empty(), "Invalid variable name.");
|
||||
return "=: " + (*this)(_assignment.variableName);
|
||||
}
|
||||
|
||||
string AsmPrinter::operator()(assembly::Assignment const& _assignment)
|
||||
string AsmPrinter::operator()(Assignment const& _assignment)
|
||||
{
|
||||
solAssert(_assignment.variableNames.size() >= 1, "");
|
||||
string variables = (*this)(_assignment.variableNames.front());
|
||||
@ -137,7 +137,7 @@ string AsmPrinter::operator()(assembly::Assignment const& _assignment)
|
||||
return variables + " := " + boost::apply_visitor(*this, *_assignment.value);
|
||||
}
|
||||
|
||||
string AsmPrinter::operator()(assembly::VariableDeclaration const& _variableDeclaration)
|
||||
string AsmPrinter::operator()(VariableDeclaration const& _variableDeclaration)
|
||||
{
|
||||
string out = "let ";
|
||||
out += boost::algorithm::join(
|
||||
@ -154,7 +154,7 @@ string AsmPrinter::operator()(assembly::VariableDeclaration const& _variableDecl
|
||||
return out;
|
||||
}
|
||||
|
||||
string AsmPrinter::operator()(assembly::FunctionDefinition const& _functionDefinition)
|
||||
string AsmPrinter::operator()(FunctionDefinition const& _functionDefinition)
|
||||
{
|
||||
solAssert(!_functionDefinition.name.empty(), "Invalid function name.");
|
||||
string out = "function " + _functionDefinition.name.str() + "(";
|
||||
@ -179,7 +179,7 @@ string AsmPrinter::operator()(assembly::FunctionDefinition const& _functionDefin
|
||||
return out + "\n" + (*this)(_functionDefinition.body);
|
||||
}
|
||||
|
||||
string AsmPrinter::operator()(assembly::FunctionCall const& _functionCall)
|
||||
string AsmPrinter::operator()(FunctionCall const& _functionCall)
|
||||
{
|
||||
return
|
||||
(*this)(_functionCall.functionName) + "(" +
|
||||
@ -210,7 +210,7 @@ string AsmPrinter::operator()(Switch const& _switch)
|
||||
return out;
|
||||
}
|
||||
|
||||
string AsmPrinter::operator()(assembly::ForLoop const& _forLoop)
|
||||
string AsmPrinter::operator()(ForLoop const& _forLoop)
|
||||
{
|
||||
solAssert(_forLoop.condition, "Invalid for loop condition.");
|
||||
string out = "for ";
|
||||
|
@ -28,11 +28,7 @@
|
||||
|
||||
#include <boost/variant.hpp>
|
||||
|
||||
namespace dev
|
||||
{
|
||||
namespace solidity
|
||||
{
|
||||
namespace assembly
|
||||
namespace yul
|
||||
{
|
||||
|
||||
class AsmPrinter: public boost::static_visitor<std::string>
|
||||
@ -40,29 +36,27 @@ class AsmPrinter: public boost::static_visitor<std::string>
|
||||
public:
|
||||
explicit AsmPrinter(bool _yul = false): m_yul(_yul) {}
|
||||
|
||||
std::string operator()(assembly::Instruction const& _instruction);
|
||||
std::string operator()(assembly::Literal const& _literal);
|
||||
std::string operator()(assembly::Identifier const& _identifier);
|
||||
std::string operator()(assembly::FunctionalInstruction const& _functionalInstruction);
|
||||
std::string operator()(assembly::ExpressionStatement const& _expr);
|
||||
std::string operator()(assembly::Label const& _label);
|
||||
std::string operator()(assembly::StackAssignment const& _assignment);
|
||||
std::string operator()(assembly::Assignment const& _assignment);
|
||||
std::string operator()(assembly::VariableDeclaration const& _variableDeclaration);
|
||||
std::string operator()(assembly::FunctionDefinition const& _functionDefinition);
|
||||
std::string operator()(assembly::FunctionCall const& _functionCall);
|
||||
std::string operator()(assembly::If const& _if);
|
||||
std::string operator()(assembly::Switch const& _switch);
|
||||
std::string operator()(assembly::ForLoop const& _forLoop);
|
||||
std::string operator()(assembly::Block const& _block);
|
||||
std::string operator()(Instruction const& _instruction);
|
||||
std::string operator()(Literal const& _literal);
|
||||
std::string operator()(Identifier const& _identifier);
|
||||
std::string operator()(FunctionalInstruction const& _functionalInstruction);
|
||||
std::string operator()(ExpressionStatement const& _expr);
|
||||
std::string operator()(Label const& _label);
|
||||
std::string operator()(StackAssignment const& _assignment);
|
||||
std::string operator()(Assignment const& _assignment);
|
||||
std::string operator()(VariableDeclaration const& _variableDeclaration);
|
||||
std::string operator()(FunctionDefinition const& _functionDefinition);
|
||||
std::string operator()(FunctionCall const& _functionCall);
|
||||
std::string operator()(If const& _if);
|
||||
std::string operator()(Switch const& _switch);
|
||||
std::string operator()(ForLoop const& _forLoop);
|
||||
std::string operator()(Block const& _block);
|
||||
|
||||
private:
|
||||
std::string formatTypedName(TypedName _variable) const;
|
||||
std::string appendTypeName(yul::YulString _type) const;
|
||||
std::string appendTypeName(YulString _type) const;
|
||||
|
||||
bool m_yul = false;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -22,9 +22,9 @@
|
||||
|
||||
using namespace std;
|
||||
using namespace dev;
|
||||
using namespace dev::solidity::assembly;
|
||||
using namespace yul;
|
||||
|
||||
bool Scope::registerLabel(yul::YulString _name)
|
||||
bool Scope::registerLabel(YulString _name)
|
||||
{
|
||||
if (exists(_name))
|
||||
return false;
|
||||
@ -32,7 +32,7 @@ bool Scope::registerLabel(yul::YulString _name)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Scope::registerVariable(yul::YulString _name, YulType const& _type)
|
||||
bool Scope::registerVariable(YulString _name, YulType const& _type)
|
||||
{
|
||||
if (exists(_name))
|
||||
return false;
|
||||
@ -42,7 +42,7 @@ bool Scope::registerVariable(yul::YulString _name, YulType const& _type)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Scope::registerFunction(yul::YulString _name, std::vector<YulType> const& _arguments, std::vector<YulType> const& _returns)
|
||||
bool Scope::registerFunction(YulString _name, std::vector<YulType> const& _arguments, std::vector<YulType> const& _returns)
|
||||
{
|
||||
if (exists(_name))
|
||||
return false;
|
||||
@ -50,7 +50,7 @@ bool Scope::registerFunction(yul::YulString _name, std::vector<YulType> const& _
|
||||
return true;
|
||||
}
|
||||
|
||||
Scope::Identifier* Scope::lookup(yul::YulString _name)
|
||||
Scope::Identifier* Scope::lookup(YulString _name)
|
||||
{
|
||||
bool crossedFunctionBoundary = false;
|
||||
for (Scope* s = this; s; s = s->superScope)
|
||||
@ -70,7 +70,7 @@ Scope::Identifier* Scope::lookup(yul::YulString _name)
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool Scope::exists(yul::YulString _name) const
|
||||
bool Scope::exists(YulString _name) const
|
||||
{
|
||||
if (identifiers.count(_name))
|
||||
return true;
|
||||
|
@ -32,16 +32,12 @@
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
|
||||
namespace dev
|
||||
{
|
||||
namespace solidity
|
||||
{
|
||||
namespace assembly
|
||||
namespace yul
|
||||
{
|
||||
|
||||
struct Scope
|
||||
{
|
||||
using YulType = yul::YulString;
|
||||
using YulType = YulString;
|
||||
using LabelID = size_t;
|
||||
|
||||
struct Variable { YulType type; };
|
||||
@ -53,13 +49,13 @@ struct Scope
|
||||
};
|
||||
|
||||
using Identifier = boost::variant<Variable, Label, Function>;
|
||||
using Visitor = GenericVisitor<Variable const, Label const, Function const>;
|
||||
using NonconstVisitor = GenericVisitor<Variable, Label, Function>;
|
||||
using Visitor = dev::GenericVisitor<Variable const, Label const, Function const>;
|
||||
using NonconstVisitor = dev::GenericVisitor<Variable, Label, Function>;
|
||||
|
||||
bool registerVariable(yul::YulString _name, YulType const& _type);
|
||||
bool registerLabel(yul::YulString _name);
|
||||
bool registerVariable(YulString _name, YulType const& _type);
|
||||
bool registerLabel(YulString _name);
|
||||
bool registerFunction(
|
||||
yul::YulString _name,
|
||||
YulString _name,
|
||||
std::vector<YulType> const& _arguments,
|
||||
std::vector<YulType> const& _returns
|
||||
);
|
||||
@ -69,12 +65,12 @@ struct Scope
|
||||
/// will any lookups across assembly boundaries.
|
||||
/// The pointer will be invalidated if the scope is modified.
|
||||
/// @param _crossedFunction if true, we already crossed a function boundary during recursive lookup
|
||||
Identifier* lookup(yul::YulString _name);
|
||||
Identifier* lookup(YulString _name);
|
||||
/// Looks up the identifier in this and super scopes (will not find variables across function
|
||||
/// boundaries and generally stops at assembly boundaries) and calls the visitor, returns
|
||||
/// false if not found.
|
||||
template <class V>
|
||||
bool lookup(yul::YulString _name, V const& _visitor)
|
||||
bool lookup(YulString _name, V const& _visitor)
|
||||
{
|
||||
if (Identifier* id = lookup(_name))
|
||||
{
|
||||
@ -86,7 +82,7 @@ struct Scope
|
||||
}
|
||||
/// @returns true if the name exists in this scope or in super scopes (also searches
|
||||
/// across function and assembly boundaries).
|
||||
bool exists(yul::YulString _name) const;
|
||||
bool exists(YulString _name) const;
|
||||
|
||||
/// @returns the number of variables directly registered inside the scope.
|
||||
size_t numberOfVariables() const;
|
||||
@ -97,9 +93,7 @@ struct Scope
|
||||
/// If true, variables from the super scope are not visible here (other identifiers are),
|
||||
/// but they are still taken into account to prevent shadowing.
|
||||
bool functionScope = false;
|
||||
std::map<yul::YulString, Identifier> identifiers;
|
||||
std::map<YulString, Identifier> identifiers;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -37,8 +37,8 @@
|
||||
using namespace std;
|
||||
using namespace dev;
|
||||
using namespace langutil;
|
||||
using namespace yul;
|
||||
using namespace dev::solidity;
|
||||
using namespace dev::solidity::assembly;
|
||||
|
||||
ScopeFiller::ScopeFiller(AsmAnalysisInfo& _info, ErrorReporter& _errorReporter):
|
||||
m_info(_info), m_errorReporter(_errorReporter)
|
||||
@ -65,7 +65,7 @@ bool ScopeFiller::operator()(Label const& _item)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ScopeFiller::operator()(assembly::VariableDeclaration const& _varDecl)
|
||||
bool ScopeFiller::operator()(VariableDeclaration const& _varDecl)
|
||||
{
|
||||
for (auto const& variable: _varDecl.variables)
|
||||
if (!registerVariable(variable, _varDecl.location, *m_currentScope))
|
||||
@ -73,7 +73,7 @@ bool ScopeFiller::operator()(assembly::VariableDeclaration const& _varDecl)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ScopeFiller::operator()(assembly::FunctionDefinition const& _funDef)
|
||||
bool ScopeFiller::operator()(FunctionDefinition const& _funDef)
|
||||
{
|
||||
bool success = true;
|
||||
vector<Scope::YulType> arguments;
|
||||
|
@ -33,11 +33,7 @@ class ErrorReporter;
|
||||
struct SourceLocation;
|
||||
}
|
||||
|
||||
namespace dev
|
||||
{
|
||||
namespace solidity
|
||||
{
|
||||
namespace assembly
|
||||
namespace yul
|
||||
{
|
||||
|
||||
struct TypedName;
|
||||
@ -53,21 +49,21 @@ class ScopeFiller: public boost::static_visitor<bool>
|
||||
public:
|
||||
ScopeFiller(AsmAnalysisInfo& _info, langutil::ErrorReporter& _errorReporter);
|
||||
|
||||
bool operator()(assembly::Instruction const&) { return true; }
|
||||
bool operator()(assembly::Literal const&) { return true; }
|
||||
bool operator()(assembly::Identifier const&) { return true; }
|
||||
bool operator()(assembly::FunctionalInstruction const&) { return true; }
|
||||
bool operator()(assembly::ExpressionStatement const& _expr);
|
||||
bool operator()(assembly::Label const& _label);
|
||||
bool operator()(assembly::StackAssignment const&) { return true; }
|
||||
bool operator()(assembly::Assignment const&) { return true; }
|
||||
bool operator()(assembly::VariableDeclaration const& _variableDeclaration);
|
||||
bool operator()(assembly::FunctionDefinition const& _functionDefinition);
|
||||
bool operator()(assembly::FunctionCall const&) { return true; }
|
||||
bool operator()(assembly::If const& _if);
|
||||
bool operator()(assembly::Switch const& _switch);
|
||||
bool operator()(assembly::ForLoop const& _forLoop);
|
||||
bool operator()(assembly::Block const& _block);
|
||||
bool operator()(Instruction const&) { return true; }
|
||||
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()(Label const& _label);
|
||||
bool operator()(StackAssignment const&) { return true; }
|
||||
bool operator()(Assignment const&) { return true; }
|
||||
bool operator()(VariableDeclaration const& _variableDeclaration);
|
||||
bool operator()(FunctionDefinition const& _functionDefinition);
|
||||
bool operator()(FunctionCall const&) { return true; }
|
||||
bool operator()(If const& _if);
|
||||
bool operator()(Switch const& _switch);
|
||||
bool operator()(ForLoop const& _forLoop);
|
||||
bool operator()(Block const& _block);
|
||||
|
||||
private:
|
||||
bool registerVariable(
|
||||
@ -76,7 +72,7 @@ private:
|
||||
Scope& _scope
|
||||
);
|
||||
|
||||
Scope& scope(assembly::Block const* _block);
|
||||
Scope& scope(Block const* _block);
|
||||
|
||||
Scope* m_currentScope = nullptr;
|
||||
AsmAnalysisInfo& m_info;
|
||||
@ -84,5 +80,3 @@ private:
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -23,18 +23,15 @@
|
||||
#include <libdevcore/Exceptions.h>
|
||||
#include <libdevcore/Assertions.h>
|
||||
|
||||
namespace dev
|
||||
{
|
||||
namespace yul
|
||||
{
|
||||
|
||||
struct YulException: virtual Exception {};
|
||||
struct YulException: virtual dev::Exception {};
|
||||
struct OptimizerException: virtual YulException {};
|
||||
struct YulAssertion: virtual YulException {};
|
||||
|
||||
/// Assertion that throws an YulAssertion containing the given description if it is not met.
|
||||
#define yulAssert(CONDITION, DESCRIPTION) \
|
||||
assertThrow(CONDITION, ::dev::yul::YulException, DESCRIPTION)
|
||||
assertThrow(CONDITION, ::yul::YulException, DESCRIPTION)
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -27,8 +27,6 @@
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
namespace dev
|
||||
{
|
||||
namespace yul
|
||||
{
|
||||
|
||||
@ -130,4 +128,3 @@ private:
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -22,6 +22,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <libdevcore/Common.h>
|
||||
#include <libdevcore/CommonData.h>
|
||||
|
||||
#include <functional>
|
||||
@ -36,14 +37,13 @@ namespace dev
|
||||
namespace solidity
|
||||
{
|
||||
enum class Instruction: uint8_t;
|
||||
namespace assembly
|
||||
}
|
||||
}
|
||||
|
||||
namespace yul
|
||||
{
|
||||
struct Instruction;
|
||||
struct Identifier;
|
||||
}
|
||||
}
|
||||
namespace yul
|
||||
{
|
||||
|
||||
///
|
||||
/// Assembly class that abstracts both the libevmasm assembly and the new Yul assembly.
|
||||
@ -61,9 +61,9 @@ public:
|
||||
/// at the beginning.
|
||||
virtual int stackHeight() const = 0;
|
||||
/// Append an EVM instruction.
|
||||
virtual void appendInstruction(solidity::Instruction _instruction) = 0;
|
||||
virtual void appendInstruction(dev::solidity::Instruction _instruction) = 0;
|
||||
/// Append a constant.
|
||||
virtual void appendConstant(u256 const& _constant) = 0;
|
||||
virtual void appendConstant(dev::u256 const& _constant) = 0;
|
||||
/// Append a label.
|
||||
virtual void appendLabel(LabelID _labelId) = 0;
|
||||
/// Append a label reference.
|
||||
@ -106,18 +106,15 @@ enum class IdentifierContext { LValue, RValue };
|
||||
/// to inline assembly (not used in standalone assembly mode).
|
||||
struct ExternalIdentifierAccess
|
||||
{
|
||||
using Resolver = std::function<size_t(solidity::assembly::Identifier const&, IdentifierContext, bool /*_crossesFunctionBoundary*/)>;
|
||||
using Resolver = std::function<size_t(Identifier const&, IdentifierContext, bool /*_crossesFunctionBoundary*/)>;
|
||||
/// Resolve an external reference given by the identifier in the given context.
|
||||
/// @returns the size of the value (number of stack slots) or size_t(-1) if not found.
|
||||
Resolver resolve;
|
||||
using CodeGenerator = std::function<void(solidity::assembly::Identifier const&, IdentifierContext, yul::AbstractAssembly&)>;
|
||||
using CodeGenerator = std::function<void(Identifier const&, IdentifierContext, yul::AbstractAssembly&)>;
|
||||
/// Generate code for retrieving the value (rvalue context) or storing the value (lvalue context)
|
||||
/// of an identifier. The code should be appended to the assembly. In rvalue context, the value is supposed
|
||||
/// to be put onto the stack, in lvalue context, the value is assumed to be at the top of the stack.
|
||||
CodeGenerator generateCode;
|
||||
};
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -27,7 +27,7 @@
|
||||
using namespace std;
|
||||
using namespace dev;
|
||||
using namespace langutil;
|
||||
using namespace dev::yul;
|
||||
using namespace yul;
|
||||
|
||||
namespace
|
||||
{
|
||||
|
@ -31,8 +31,6 @@ namespace langutil
|
||||
struct SourceLocation;
|
||||
}
|
||||
|
||||
namespace dev
|
||||
{
|
||||
namespace yul
|
||||
{
|
||||
|
||||
@ -48,9 +46,9 @@ public:
|
||||
/// at the beginning.
|
||||
int stackHeight() const override { return m_stackHeight; }
|
||||
/// Append an EVM instruction.
|
||||
void appendInstruction(solidity::Instruction _instruction) override;
|
||||
void appendInstruction(dev::solidity::Instruction _instruction) override;
|
||||
/// Append a constant.
|
||||
void appendConstant(u256 const& _constant) override;
|
||||
void appendConstant(dev::u256 const& _constant) override;
|
||||
/// Append a label.
|
||||
void appendLabel(LabelID _labelId) override;
|
||||
/// Append a label reference.
|
||||
@ -81,17 +79,17 @@ public:
|
||||
void appendAssemblySize() override;
|
||||
|
||||
/// Resolves references inside the bytecode and returns the linker object.
|
||||
eth::LinkerObject finalize();
|
||||
dev::eth::LinkerObject finalize();
|
||||
|
||||
private:
|
||||
void setLabelToCurrentPosition(AbstractAssembly::LabelID _labelId);
|
||||
void appendLabelReferenceInternal(AbstractAssembly::LabelID _labelId);
|
||||
void updateReference(size_t pos, size_t size, u256 value);
|
||||
void updateReference(size_t pos, size_t size, dev::u256 value);
|
||||
|
||||
bool m_evm15 = false; ///< if true, switch to evm1.5 mode
|
||||
LabelID m_nextLabelId = 0;
|
||||
int m_stackHeight = 0;
|
||||
bytes m_bytecode;
|
||||
dev::bytes m_bytecode;
|
||||
std::map<std::string, LabelID> m_namedLabels;
|
||||
std::map<LabelID, size_t> m_labelPositions;
|
||||
std::map<size_t, LabelID> m_labelReferences;
|
||||
@ -99,4 +97,3 @@ private:
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -29,11 +29,9 @@
|
||||
|
||||
using namespace std;
|
||||
using namespace dev;
|
||||
using namespace dev::yul;
|
||||
using namespace yul;
|
||||
using namespace dev::solidity;
|
||||
|
||||
using Scope = dev::solidity::assembly::Scope;
|
||||
|
||||
void CodeTransform::operator()(VariableDeclaration const& _varDecl)
|
||||
{
|
||||
solAssert(m_scope, "");
|
||||
@ -147,7 +145,7 @@ void CodeTransform::operator()(FunctionalInstruction const& _instruction)
|
||||
solAssert(_instruction.arguments.size() == 1, "");
|
||||
}
|
||||
m_assembly.setSourceLocation(_instruction.location);
|
||||
auto label = labelFromIdentifier(boost::get<assembly::Identifier>(_instruction.arguments.at(0)));
|
||||
auto label = labelFromIdentifier(boost::get<Identifier>(_instruction.arguments.at(0)));
|
||||
if (isJumpI)
|
||||
m_assembly.appendJumpToIf(label);
|
||||
else
|
||||
@ -163,7 +161,7 @@ void CodeTransform::operator()(FunctionalInstruction const& _instruction)
|
||||
checkStackHeight(&_instruction);
|
||||
}
|
||||
|
||||
void CodeTransform::operator()(assembly::Identifier const& _identifier)
|
||||
void CodeTransform::operator()(Identifier const& _identifier)
|
||||
{
|
||||
m_assembly.setSourceLocation(_identifier.location);
|
||||
// First search internals, then externals.
|
||||
@ -197,12 +195,12 @@ void CodeTransform::operator()(assembly::Identifier const& _identifier)
|
||||
checkStackHeight(&_identifier);
|
||||
}
|
||||
|
||||
void CodeTransform::operator()(assembly::Literal const& _literal)
|
||||
void CodeTransform::operator()(Literal const& _literal)
|
||||
{
|
||||
m_assembly.setSourceLocation(_literal.location);
|
||||
if (_literal.kind == assembly::LiteralKind::Number)
|
||||
if (_literal.kind == LiteralKind::Number)
|
||||
m_assembly.appendConstant(u256(_literal.value.str()));
|
||||
else if (_literal.kind == assembly::LiteralKind::Boolean)
|
||||
else if (_literal.kind == LiteralKind::Boolean)
|
||||
{
|
||||
if (_literal.value.str() == "true")
|
||||
m_assembly.appendConstant(u256(1));
|
||||
@ -217,7 +215,7 @@ void CodeTransform::operator()(assembly::Literal const& _literal)
|
||||
checkStackHeight(&_literal);
|
||||
}
|
||||
|
||||
void CodeTransform::operator()(assembly::Instruction const& _instruction)
|
||||
void CodeTransform::operator()(yul::Instruction const& _instruction)
|
||||
{
|
||||
solAssert(!m_evm15 || _instruction.instruction != solidity::Instruction::JUMP, "Bare JUMP instruction used for EVM1.5");
|
||||
solAssert(!m_evm15 || _instruction.instruction != solidity::Instruction::JUMPI, "Bare JUMPI instruction used for EVM1.5");
|
||||
@ -522,7 +520,7 @@ void CodeTransform::generateAssignment(Identifier const& _variableName)
|
||||
}
|
||||
}
|
||||
|
||||
int CodeTransform::variableHeightDiff(solidity::assembly::Scope::Variable const& _var, bool _forSwap) const
|
||||
int CodeTransform::variableHeightDiff(Scope::Variable const& _var, bool _forSwap) const
|
||||
{
|
||||
solAssert(m_context->variableStackHeights.count(&_var), "");
|
||||
int heightDiff = m_assembly.stackHeight() - m_context->variableStackHeights[&_var];
|
||||
|
@ -27,18 +27,14 @@
|
||||
#include <boost/variant.hpp>
|
||||
#include <boost/optional.hpp>
|
||||
|
||||
namespace dev
|
||||
{
|
||||
namespace solidity
|
||||
namespace langutil
|
||||
{
|
||||
class ErrorReporter;
|
||||
namespace assembly
|
||||
{
|
||||
struct AsmAnalysisInfo;
|
||||
}
|
||||
}
|
||||
|
||||
namespace yul
|
||||
{
|
||||
struct AsmAnalysisInfo;
|
||||
class EVMAssembly;
|
||||
|
||||
class CodeTransform: public boost::static_visitor<>
|
||||
@ -47,8 +43,8 @@ public:
|
||||
/// Create the code transformer.
|
||||
/// @param _identifierAccess used to resolve identifiers external to the inline assembly
|
||||
CodeTransform(
|
||||
yul::AbstractAssembly& _assembly,
|
||||
solidity::assembly::AsmAnalysisInfo& _analysisInfo,
|
||||
AbstractAssembly& _assembly,
|
||||
AsmAnalysisInfo& _analysisInfo,
|
||||
bool _yul = false,
|
||||
bool _evm15 = false,
|
||||
ExternalIdentifierAccess const& _identifierAccess = ExternalIdentifierAccess(),
|
||||
@ -69,15 +65,14 @@ public:
|
||||
protected:
|
||||
struct Context
|
||||
{
|
||||
using Scope = solidity::assembly::Scope;
|
||||
std::map<Scope::Label const*, AbstractAssembly::LabelID> labelIDs;
|
||||
std::map<Scope::Function const*, AbstractAssembly::LabelID> functionEntryIDs;
|
||||
std::map<Scope::Variable const*, int> variableStackHeights;
|
||||
};
|
||||
|
||||
CodeTransform(
|
||||
yul::AbstractAssembly& _assembly,
|
||||
solidity::assembly::AsmAnalysisInfo& _analysisInfo,
|
||||
AbstractAssembly& _assembly,
|
||||
AsmAnalysisInfo& _analysisInfo,
|
||||
bool _yul,
|
||||
bool _evm15,
|
||||
ExternalIdentifierAccess const& _identifierAccess,
|
||||
@ -116,8 +111,8 @@ private:
|
||||
AbstractAssembly::LabelID labelFromIdentifier(Identifier const& _identifier);
|
||||
/// @returns the label ID corresponding to the given label, allocating a new one if
|
||||
/// necessary.
|
||||
AbstractAssembly::LabelID labelID(solidity::assembly::Scope::Label const& _label);
|
||||
AbstractAssembly::LabelID functionEntryID(YulString _name, solidity::assembly::Scope::Function const& _function);
|
||||
AbstractAssembly::LabelID labelID(Scope::Label const& _label);
|
||||
AbstractAssembly::LabelID functionEntryID(YulString _name, Scope::Function const& _function);
|
||||
/// Generates code for an expression that is supposed to return a single value.
|
||||
void visitExpression(Expression const& _expression);
|
||||
|
||||
@ -133,15 +128,15 @@ private:
|
||||
/// Determines the stack height difference to the given variables. Throws
|
||||
/// if it is not yet in scope or the height difference is too large. Returns
|
||||
/// the (positive) stack height difference otherwise.
|
||||
int variableHeightDiff(solidity::assembly::Scope::Variable const& _var, bool _forSwap) const;
|
||||
int variableHeightDiff(Scope::Variable const& _var, bool _forSwap) const;
|
||||
|
||||
void expectDeposit(int _deposit, int _oldHeight) const;
|
||||
|
||||
void checkStackHeight(void const* _astElement) const;
|
||||
|
||||
yul::AbstractAssembly& m_assembly;
|
||||
solidity::assembly::AsmAnalysisInfo& m_info;
|
||||
solidity::assembly::Scope* m_scope = nullptr;
|
||||
AbstractAssembly& m_assembly;
|
||||
AsmAnalysisInfo& m_info;
|
||||
Scope* m_scope = nullptr;
|
||||
bool m_yul = false;
|
||||
bool m_evm15 = false;
|
||||
bool m_useNamedLabelsForFunctions = false;
|
||||
@ -155,4 +150,3 @@ private:
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -28,7 +28,7 @@
|
||||
|
||||
using namespace std;
|
||||
using namespace dev;
|
||||
using namespace dev::yul;
|
||||
using namespace yul;
|
||||
|
||||
Statement ASTCopier::operator()(Instruction const&)
|
||||
{
|
||||
|
@ -31,8 +31,6 @@
|
||||
#include <set>
|
||||
#include <memory>
|
||||
|
||||
namespace dev
|
||||
{
|
||||
namespace yul
|
||||
{
|
||||
|
||||
@ -123,4 +121,3 @@ std::vector<T> ASTCopier::translateVector(std::vector<T> const& _values)
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -26,7 +26,7 @@
|
||||
|
||||
using namespace std;
|
||||
using namespace dev;
|
||||
using namespace dev::yul;
|
||||
using namespace yul;
|
||||
using namespace dev::solidity;
|
||||
|
||||
|
||||
|
@ -32,8 +32,6 @@
|
||||
#include <set>
|
||||
#include <map>
|
||||
|
||||
namespace dev
|
||||
{
|
||||
namespace yul
|
||||
{
|
||||
|
||||
@ -120,4 +118,3 @@ protected:
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -22,7 +22,7 @@
|
||||
|
||||
using namespace std;
|
||||
using namespace dev;
|
||||
using namespace dev::yul;
|
||||
using namespace yul;
|
||||
|
||||
void BlockFlattener::operator()(Block& _block)
|
||||
{
|
||||
|
@ -18,8 +18,6 @@
|
||||
|
||||
#include <libyul/optimiser/ASTWalker.h>
|
||||
|
||||
namespace dev
|
||||
{
|
||||
namespace yul
|
||||
{
|
||||
|
||||
@ -31,4 +29,3 @@ public:
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -28,7 +28,7 @@
|
||||
|
||||
using namespace std;
|
||||
using namespace dev;
|
||||
using namespace dev::yul;
|
||||
using namespace yul;
|
||||
|
||||
void CommonSubexpressionEliminator::visit(Expression& _e)
|
||||
{
|
||||
|
@ -23,8 +23,6 @@
|
||||
|
||||
#include <libyul/optimiser/DataFlowAnalyzer.h>
|
||||
|
||||
namespace dev
|
||||
{
|
||||
namespace yul
|
||||
{
|
||||
|
||||
@ -42,4 +40,3 @@ protected:
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -33,7 +33,7 @@
|
||||
|
||||
using namespace std;
|
||||
using namespace dev;
|
||||
using namespace dev::yul;
|
||||
using namespace yul;
|
||||
|
||||
void DataFlowAnalyzer::operator()(Assignment& _assignment)
|
||||
{
|
||||
|
@ -28,8 +28,6 @@
|
||||
#include <map>
|
||||
#include <set>
|
||||
|
||||
namespace dev
|
||||
{
|
||||
namespace yul
|
||||
{
|
||||
|
||||
@ -87,4 +85,3 @@ protected:
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -26,11 +26,9 @@
|
||||
|
||||
using namespace std;
|
||||
using namespace dev;
|
||||
using namespace dev::yul;
|
||||
using namespace yul;
|
||||
using namespace dev::solidity;
|
||||
|
||||
using Scope = dev::solidity::assembly::Scope;
|
||||
|
||||
YulString Disambiguator::translateIdentifier(YulString _originalName)
|
||||
{
|
||||
if ((m_externallyUsedIdentifiers.count(_originalName)))
|
||||
|
@ -30,8 +30,6 @@
|
||||
|
||||
#include <set>
|
||||
|
||||
namespace dev
|
||||
{
|
||||
namespace yul
|
||||
{
|
||||
|
||||
@ -42,7 +40,7 @@ class Disambiguator: public ASTCopier
|
||||
{
|
||||
public:
|
||||
explicit Disambiguator(
|
||||
solidity::assembly::AsmAnalysisInfo const& _analysisInfo,
|
||||
AsmAnalysisInfo const& _analysisInfo,
|
||||
std::set<YulString> const& _externallyUsedIdentifiers = {}
|
||||
):
|
||||
m_info(_analysisInfo), m_externallyUsedIdentifiers(_externallyUsedIdentifiers), m_nameDispenser(m_externallyUsedIdentifiers)
|
||||
@ -56,16 +54,15 @@ protected:
|
||||
void leaveFunction(FunctionDefinition const& _function) override;
|
||||
YulString translateIdentifier(YulString _name) override;
|
||||
|
||||
void enterScopeInternal(solidity::assembly::Scope& _scope);
|
||||
void leaveScopeInternal(solidity::assembly::Scope& _scope);
|
||||
void enterScopeInternal(Scope& _scope);
|
||||
void leaveScopeInternal(Scope& _scope);
|
||||
|
||||
solidity::assembly::AsmAnalysisInfo const& m_info;
|
||||
AsmAnalysisInfo const& m_info;
|
||||
std::set<YulString> const& m_externallyUsedIdentifiers;
|
||||
|
||||
std::vector<solidity::assembly::Scope*> m_scopes;
|
||||
std::vector<Scope*> m_scopes;
|
||||
std::map<void const*, YulString> m_translations;
|
||||
NameDispenser m_nameDispenser;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -29,7 +29,7 @@
|
||||
|
||||
using namespace std;
|
||||
using namespace dev;
|
||||
using namespace dev::yul;
|
||||
using namespace yul;
|
||||
using namespace dev::solidity;
|
||||
|
||||
void ExpressionInliner::run()
|
||||
|
@ -27,8 +27,6 @@
|
||||
|
||||
#include <set>
|
||||
|
||||
namespace dev
|
||||
{
|
||||
namespace yul
|
||||
{
|
||||
|
||||
@ -68,4 +66,3 @@ private:
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -32,7 +32,7 @@
|
||||
|
||||
using namespace std;
|
||||
using namespace dev;
|
||||
using namespace dev::yul;
|
||||
using namespace yul;
|
||||
using namespace dev::solidity;
|
||||
|
||||
void ExpressionJoiner::operator()(FunctionalInstruction& _instruction)
|
||||
|
@ -25,8 +25,6 @@
|
||||
|
||||
#include <map>
|
||||
|
||||
namespace dev
|
||||
{
|
||||
namespace yul
|
||||
{
|
||||
|
||||
@ -98,4 +96,3 @@ private:
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -29,7 +29,7 @@
|
||||
|
||||
using namespace std;
|
||||
using namespace dev;
|
||||
using namespace dev::yul;
|
||||
using namespace yul;
|
||||
using namespace dev::solidity;
|
||||
|
||||
|
||||
|
@ -24,8 +24,6 @@
|
||||
|
||||
#include <libyul/optimiser/ASTWalker.h>
|
||||
|
||||
namespace dev
|
||||
{
|
||||
namespace yul
|
||||
{
|
||||
|
||||
@ -52,4 +50,3 @@ private:
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -32,7 +32,7 @@
|
||||
using namespace std;
|
||||
using namespace dev;
|
||||
using namespace langutil;
|
||||
using namespace dev::yul;
|
||||
using namespace yul;
|
||||
using namespace dev::solidity;
|
||||
|
||||
void ExpressionSplitter::operator()(FunctionalInstruction& _instruction)
|
||||
|
@ -27,8 +27,6 @@
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace dev
|
||||
{
|
||||
namespace yul
|
||||
{
|
||||
|
||||
@ -83,4 +81,3 @@ private:
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -21,7 +21,7 @@
|
||||
|
||||
using namespace std;
|
||||
using namespace dev;
|
||||
using namespace dev::yul;
|
||||
using namespace yul;
|
||||
|
||||
void ForLoopInitRewriter::operator()(Block& _block)
|
||||
{
|
||||
|
@ -18,8 +18,6 @@
|
||||
|
||||
#include <libyul/optimiser/ASTWalker.h>
|
||||
|
||||
namespace dev
|
||||
{
|
||||
namespace yul
|
||||
{
|
||||
|
||||
@ -36,4 +34,3 @@ public:
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -36,7 +36,7 @@
|
||||
|
||||
using namespace std;
|
||||
using namespace dev;
|
||||
using namespace dev::yul;
|
||||
using namespace yul;
|
||||
using namespace dev::solidity;
|
||||
|
||||
FullInliner::FullInliner(Block& _ast, NameDispenser& _dispenser):
|
||||
|
@ -33,8 +33,6 @@
|
||||
|
||||
#include <set>
|
||||
|
||||
namespace dev
|
||||
{
|
||||
namespace yul
|
||||
{
|
||||
|
||||
@ -153,4 +151,3 @@ public:
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -27,7 +27,7 @@
|
||||
|
||||
using namespace std;
|
||||
using namespace dev;
|
||||
using namespace dev::yul;
|
||||
using namespace yul;
|
||||
using namespace dev::solidity;
|
||||
|
||||
|
||||
|
@ -23,8 +23,6 @@
|
||||
|
||||
#include <libyul/ASTDataForward.h>
|
||||
|
||||
namespace dev
|
||||
{
|
||||
namespace yul
|
||||
{
|
||||
|
||||
@ -43,4 +41,3 @@ public:
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -28,7 +28,7 @@
|
||||
|
||||
using namespace std;
|
||||
using namespace dev;
|
||||
using namespace dev::yul;
|
||||
using namespace yul;
|
||||
using namespace dev::solidity;
|
||||
|
||||
void FunctionHoister::operator()(Block& _block)
|
||||
|
@ -24,8 +24,6 @@
|
||||
#include <libyul/ASTDataForward.h>
|
||||
#include <libyul/optimiser/ASTWalker.h>
|
||||
|
||||
namespace dev
|
||||
{
|
||||
namespace yul
|
||||
{
|
||||
|
||||
@ -48,4 +46,3 @@ private:
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -25,7 +25,7 @@
|
||||
|
||||
using namespace std;
|
||||
using namespace dev;
|
||||
using namespace dev::yul;
|
||||
using namespace yul;
|
||||
|
||||
void InlinableExpressionFunctionFinder::operator()(Identifier const& _identifier)
|
||||
{
|
||||
|
@ -25,8 +25,6 @@
|
||||
|
||||
#include <set>
|
||||
|
||||
namespace dev
|
||||
{
|
||||
namespace yul
|
||||
{
|
||||
|
||||
@ -66,4 +64,3 @@ private:
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -30,7 +30,7 @@
|
||||
|
||||
using namespace std;
|
||||
using namespace dev;
|
||||
using namespace dev::yul;
|
||||
using namespace yul;
|
||||
using namespace dev::solidity;
|
||||
|
||||
void MainFunction::operator()(Block& _block)
|
||||
|
@ -23,8 +23,6 @@
|
||||
|
||||
#include <libyul/ASTDataForward.h>
|
||||
|
||||
namespace dev
|
||||
{
|
||||
namespace yul
|
||||
{
|
||||
|
||||
@ -38,4 +36,3 @@ public:
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -23,7 +23,7 @@
|
||||
#include <libyul/AsmData.h>
|
||||
|
||||
using namespace dev;
|
||||
using namespace dev::yul;
|
||||
using namespace yul;
|
||||
|
||||
size_t CodeSize::codeSize(Statement const& _statement)
|
||||
{
|
||||
|
@ -22,8 +22,6 @@
|
||||
|
||||
#include <libyul/optimiser/ASTWalker.h>
|
||||
|
||||
namespace dev
|
||||
{
|
||||
namespace yul
|
||||
{
|
||||
|
||||
@ -49,4 +47,3 @@ private:
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -24,7 +24,7 @@
|
||||
|
||||
using namespace std;
|
||||
using namespace dev;
|
||||
using namespace dev::yul;
|
||||
using namespace yul;
|
||||
|
||||
void NameCollector::operator()(VariableDeclaration const& _varDecl)
|
||||
{
|
||||
|
@ -25,8 +25,6 @@
|
||||
#include <map>
|
||||
#include <set>
|
||||
|
||||
namespace dev
|
||||
{
|
||||
namespace yul
|
||||
{
|
||||
|
||||
@ -83,4 +81,3 @@ private:
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -25,7 +25,7 @@
|
||||
|
||||
using namespace std;
|
||||
using namespace dev;
|
||||
using namespace dev::yul;
|
||||
using namespace yul;
|
||||
|
||||
NameDispenser::NameDispenser(Block const& _ast):
|
||||
NameDispenser(NameCollector(_ast).names())
|
||||
|
@ -25,8 +25,6 @@
|
||||
|
||||
#include <set>
|
||||
|
||||
namespace dev
|
||||
{
|
||||
namespace yul
|
||||
{
|
||||
|
||||
@ -58,4 +56,3 @@ private:
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -30,7 +30,7 @@
|
||||
|
||||
using namespace std;
|
||||
using namespace dev;
|
||||
using namespace dev::yul;
|
||||
using namespace yul;
|
||||
using namespace dev::solidity;
|
||||
|
||||
void RedundantAssignEliminator::operator()(Identifier const& _identifier)
|
||||
|
@ -26,8 +26,6 @@
|
||||
|
||||
#include <map>
|
||||
|
||||
namespace dev
|
||||
{
|
||||
namespace yul
|
||||
{
|
||||
|
||||
@ -189,4 +187,3 @@ private:
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -27,7 +27,7 @@
|
||||
|
||||
using namespace std;
|
||||
using namespace dev;
|
||||
using namespace dev::yul;
|
||||
using namespace yul;
|
||||
|
||||
void Rematerialiser::visit(Expression& _e)
|
||||
{
|
||||
|
@ -22,8 +22,6 @@
|
||||
|
||||
#include <libyul/optimiser/DataFlowAnalyzer.h>
|
||||
|
||||
namespace dev
|
||||
{
|
||||
namespace yul
|
||||
{
|
||||
|
||||
@ -41,4 +39,3 @@ protected:
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -31,7 +31,7 @@
|
||||
using namespace std;
|
||||
using namespace dev;
|
||||
using namespace langutil;
|
||||
using namespace dev::yul;
|
||||
using namespace yul;
|
||||
using namespace dev::solidity;
|
||||
|
||||
void SSATransform::operator()(Identifier& _identifier)
|
||||
|
@ -25,8 +25,6 @@
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace dev
|
||||
{
|
||||
namespace yul
|
||||
{
|
||||
|
||||
@ -94,4 +92,3 @@ private:
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -25,7 +25,7 @@
|
||||
|
||||
using namespace std;
|
||||
using namespace dev;
|
||||
using namespace dev::yul;
|
||||
using namespace yul;
|
||||
|
||||
void SSAValueTracker::operator()(Assignment const& _assignment)
|
||||
{
|
||||
|
@ -26,8 +26,6 @@
|
||||
#include <map>
|
||||
#include <set>
|
||||
|
||||
namespace dev
|
||||
{
|
||||
namespace yul
|
||||
{
|
||||
|
||||
@ -54,4 +52,3 @@ private:
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -29,7 +29,7 @@
|
||||
|
||||
using namespace std;
|
||||
using namespace dev;
|
||||
using namespace dev::yul;
|
||||
using namespace yul;
|
||||
|
||||
MovableChecker::MovableChecker(Expression const& _expression)
|
||||
{
|
||||
|
@ -24,8 +24,6 @@
|
||||
|
||||
#include <set>
|
||||
|
||||
namespace dev
|
||||
{
|
||||
namespace yul
|
||||
{
|
||||
|
||||
@ -57,4 +55,3 @@ private:
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -31,7 +31,7 @@
|
||||
using namespace std;
|
||||
using namespace dev;
|
||||
using namespace langutil;
|
||||
using namespace dev::yul;
|
||||
using namespace yul;
|
||||
|
||||
|
||||
SimplificationRule<Pattern> const* SimplificationRules::findFirstMatch(
|
||||
@ -123,7 +123,7 @@ bool Pattern::matches(Expression const& _expr, map<YulString, Expression const*>
|
||||
if (expr->type() != typeid(Literal))
|
||||
return false;
|
||||
Literal const& literal = boost::get<Literal>(*expr);
|
||||
if (literal.kind != assembly::LiteralKind::Number)
|
||||
if (literal.kind != LiteralKind::Number)
|
||||
return false;
|
||||
if (m_data && *m_data != u256(literal.value.str()))
|
||||
return false;
|
||||
@ -193,7 +193,7 @@ Expression Pattern::toExpression(SourceLocation const& _location) const
|
||||
if (m_kind == PatternKind::Constant)
|
||||
{
|
||||
assertThrow(m_data, OptimizerException, "No match group and no constant value given.");
|
||||
return Literal{_location, assembly::LiteralKind::Number, YulString{formatNumber(*m_data)}, {}};
|
||||
return Literal{_location, LiteralKind::Number, YulString{formatNumber(*m_data)}, {}};
|
||||
}
|
||||
else if (m_kind == PatternKind::Operation)
|
||||
{
|
||||
@ -208,7 +208,7 @@ Expression Pattern::toExpression(SourceLocation const& _location) const
|
||||
u256 Pattern::d() const
|
||||
{
|
||||
Literal const& literal = boost::get<Literal>(matchGroupValue());
|
||||
assertThrow(literal.kind == assembly::LiteralKind::Number, OptimizerException, "");
|
||||
assertThrow(literal.kind == LiteralKind::Number, OptimizerException, "");
|
||||
assertThrow(isValidDecimal(literal.value.str()) || isValidHex(literal.value.str()), OptimizerException, "");
|
||||
return u256(literal.value.str());
|
||||
}
|
||||
|
@ -31,8 +31,6 @@
|
||||
#include <functional>
|
||||
#include <vector>
|
||||
|
||||
namespace dev
|
||||
{
|
||||
namespace yul
|
||||
{
|
||||
|
||||
@ -85,11 +83,11 @@ public:
|
||||
/// Matches any expression.
|
||||
Pattern(PatternKind _kind = PatternKind::Any): m_kind(_kind) {}
|
||||
// Matches a specific constant value.
|
||||
Pattern(unsigned _value): Pattern(u256(_value)) {}
|
||||
Pattern(unsigned _value): Pattern(dev::u256(_value)) {}
|
||||
// Matches a specific constant value.
|
||||
Pattern(u256 const& _value): m_kind(PatternKind::Constant), m_data(std::make_shared<u256>(_value)) {}
|
||||
Pattern(dev::u256 const& _value): m_kind(PatternKind::Constant), m_data(std::make_shared<dev::u256>(_value)) {}
|
||||
// Matches a given instruction with given arguments
|
||||
Pattern(solidity::Instruction _instruction, std::vector<Pattern> const& _arguments = {});
|
||||
Pattern(dev::solidity::Instruction _instruction, std::vector<Pattern> const& _arguments = {});
|
||||
/// Sets this pattern to be part of the match group with the identifier @a _group.
|
||||
/// Inside one rule, all patterns in the same match group have to match expressions from the
|
||||
/// same expression equivalence class.
|
||||
@ -100,9 +98,9 @@ public:
|
||||
std::vector<Pattern> arguments() const { return m_arguments; }
|
||||
|
||||
/// @returns the data of the matched expression if this pattern is part of a match group.
|
||||
u256 d() const;
|
||||
dev::u256 d() const;
|
||||
|
||||
solidity::Instruction instruction() const;
|
||||
dev::solidity::Instruction instruction() const;
|
||||
|
||||
/// Turns this pattern into an actual expression. Should only be called
|
||||
/// for patterns resulting from an action, i.e. with match groups assigned.
|
||||
@ -112,12 +110,11 @@ private:
|
||||
Expression const& matchGroupValue() const;
|
||||
|
||||
PatternKind m_kind = PatternKind::Any;
|
||||
solidity::Instruction m_instruction; ///< Only valid if m_kind is Operation
|
||||
std::shared_ptr<u256> m_data; ///< Only valid if m_kind is Constant
|
||||
dev::solidity::Instruction m_instruction; ///< Only valid if m_kind is Operation
|
||||
std::shared_ptr<dev::u256> m_data; ///< Only valid if m_kind is Constant
|
||||
std::vector<Pattern> m_arguments;
|
||||
unsigned m_matchGroup = 0;
|
||||
std::map<unsigned, Expression const*>* m_matchGroups = nullptr;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -24,7 +24,7 @@
|
||||
|
||||
using namespace std;
|
||||
using namespace dev;
|
||||
using namespace dev::yul;
|
||||
using namespace yul;
|
||||
|
||||
Expression Substitution::translate(Expression const& _expression)
|
||||
{
|
||||
|
@ -25,8 +25,6 @@
|
||||
|
||||
#include <map>
|
||||
|
||||
namespace dev
|
||||
{
|
||||
namespace yul
|
||||
{
|
||||
|
||||
@ -46,4 +44,3 @@ private:
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -43,11 +43,11 @@
|
||||
|
||||
using namespace std;
|
||||
using namespace dev;
|
||||
using namespace dev::yul;
|
||||
using namespace yul;
|
||||
|
||||
void OptimiserSuite::run(
|
||||
Block& _ast,
|
||||
solidity::assembly::AsmAnalysisInfo const& _analysisInfo,
|
||||
AsmAnalysisInfo const& _analysisInfo,
|
||||
set<YulString> const& _externallyUsedIdentifiers
|
||||
)
|
||||
{
|
||||
|
@ -25,18 +25,11 @@
|
||||
|
||||
#include <set>
|
||||
|
||||
namespace dev
|
||||
{
|
||||
namespace solidity
|
||||
{
|
||||
namespace assembly
|
||||
{
|
||||
struct AsmAnalysisInfo;
|
||||
}
|
||||
}
|
||||
namespace yul
|
||||
{
|
||||
|
||||
struct AsmAnalysisInfo;
|
||||
|
||||
/**
|
||||
* Optimiser suite that combines all steps and also provides the settings for the heuristics
|
||||
*/
|
||||
@ -45,11 +38,10 @@ class OptimiserSuite
|
||||
public:
|
||||
static void run(
|
||||
Block& _ast,
|
||||
solidity::assembly::AsmAnalysisInfo const& _analysisInfo,
|
||||
AsmAnalysisInfo const& _analysisInfo,
|
||||
|
||||
std::set<YulString> const& _externallyUsedIdentifiers = {}
|
||||
);
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -27,7 +27,7 @@
|
||||
|
||||
using namespace std;
|
||||
using namespace dev;
|
||||
using namespace dev::yul;
|
||||
using namespace yul;
|
||||
|
||||
bool SyntacticalEqualityChecker::equal(Expression const& _e1, Expression const& _e2)
|
||||
{
|
||||
|
@ -24,8 +24,6 @@
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace dev
|
||||
{
|
||||
namespace yul
|
||||
{
|
||||
|
||||
@ -47,4 +45,3 @@ protected:
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -30,7 +30,7 @@
|
||||
|
||||
using namespace std;
|
||||
using namespace dev;
|
||||
using namespace dev::yul;
|
||||
using namespace yul;
|
||||
|
||||
UnusedPruner::UnusedPruner(Block& _ast, set<YulString> const& _externallyUsedFunctions)
|
||||
{
|
||||
|
@ -26,8 +26,6 @@
|
||||
#include <map>
|
||||
#include <set>
|
||||
|
||||
namespace dev
|
||||
{
|
||||
namespace yul
|
||||
{
|
||||
|
||||
@ -62,4 +60,3 @@ private:
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -28,9 +28,9 @@
|
||||
|
||||
using namespace std;
|
||||
using namespace dev;
|
||||
using namespace dev::yul;
|
||||
using namespace yul;
|
||||
|
||||
void dev::yul::removeEmptyBlocks(Block& _block)
|
||||
void yul::removeEmptyBlocks(Block& _block)
|
||||
{
|
||||
auto isEmptyBlock = [](Statement const& _st) -> bool {
|
||||
return _st.type() == typeid(Block) && boost::get<Block>(_st).statements.empty();
|
||||
|
@ -22,8 +22,6 @@
|
||||
|
||||
#include <libyul/ASTDataForward.h>
|
||||
|
||||
namespace dev
|
||||
{
|
||||
namespace yul
|
||||
{
|
||||
|
||||
@ -31,4 +29,3 @@ namespace yul
|
||||
void removeEmptyBlocks(Block& _block);
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -24,10 +24,7 @@
|
||||
|
||||
using namespace std;
|
||||
using namespace dev;
|
||||
using namespace dev::yul;
|
||||
|
||||
using dev::solidity::assembly::TypedName;
|
||||
using dev::solidity::assembly::TypedNameList;
|
||||
using namespace yul;
|
||||
|
||||
void VarDeclPropagator::operator()(Block& _block)
|
||||
{
|
||||
|
@ -25,8 +25,6 @@
|
||||
#include <set>
|
||||
#include <map>
|
||||
|
||||
namespace dev
|
||||
{
|
||||
namespace yul
|
||||
{
|
||||
|
||||
@ -60,4 +58,3 @@ private:
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -143,7 +143,7 @@ test_suite* init_unit_test_suite( int /*argc*/, char* /*argv*/[] )
|
||||
master,
|
||||
dev::test::Options::get().testPath / "libyul",
|
||||
"yulOptimizerTests",
|
||||
dev::yul::test::YulOptimizerTest::create
|
||||
yul::test::YulOptimizerTest::create
|
||||
) > 0, "no Yul Optimizer tests found");
|
||||
if (!dev::test::Options::get().disableSMT)
|
||||
solAssert(registerTests(
|
||||
|
@ -37,10 +37,10 @@
|
||||
|
||||
using namespace std;
|
||||
using namespace langutil;
|
||||
using namespace dev::yul;
|
||||
using namespace yul;
|
||||
using namespace dev::solidity;
|
||||
|
||||
void dev::yul::test::printErrors(ErrorList const& _errors, Scanner const& _scanner)
|
||||
void yul::test::printErrors(ErrorList const& _errors, Scanner const& _scanner)
|
||||
{
|
||||
SourceReferenceFormatter formatter(cout, [&](std::string const&) -> Scanner const& { return _scanner; });
|
||||
|
||||
@ -52,18 +52,18 @@ void dev::yul::test::printErrors(ErrorList const& _errors, Scanner const& _scann
|
||||
}
|
||||
|
||||
|
||||
pair<shared_ptr<Block>, shared_ptr<assembly::AsmAnalysisInfo>> dev::yul::test::parse(string const& _source, bool _yul)
|
||||
pair<shared_ptr<Block>, shared_ptr<yul::AsmAnalysisInfo>> yul::test::parse(string const& _source, bool _yul)
|
||||
{
|
||||
auto flavour = _yul ? assembly::AsmFlavour::Yul : assembly::AsmFlavour::Strict;
|
||||
auto flavour = _yul ? yul::AsmFlavour::Yul : yul::AsmFlavour::Strict;
|
||||
ErrorList errors;
|
||||
ErrorReporter errorReporter(errors);
|
||||
auto scanner = make_shared<Scanner>(CharStream(_source), "");
|
||||
auto parserResult = assembly::Parser(errorReporter, flavour).parse(scanner, false);
|
||||
auto parserResult = yul::Parser(errorReporter, flavour).parse(scanner, false);
|
||||
if (parserResult)
|
||||
{
|
||||
BOOST_REQUIRE(errorReporter.errors().empty());
|
||||
auto analysisInfo = make_shared<assembly::AsmAnalysisInfo>();
|
||||
assembly::AsmAnalyzer analyzer(
|
||||
auto analysisInfo = make_shared<yul::AsmAnalysisInfo>();
|
||||
yul::AsmAnalyzer analyzer(
|
||||
*analysisInfo,
|
||||
errorReporter,
|
||||
dev::test::Options::get().evmVersion(),
|
||||
@ -83,13 +83,13 @@ pair<shared_ptr<Block>, shared_ptr<assembly::AsmAnalysisInfo>> dev::yul::test::p
|
||||
return {};
|
||||
}
|
||||
|
||||
assembly::Block dev::yul::test::disambiguate(string const& _source, bool _yul)
|
||||
yul::Block yul::test::disambiguate(string const& _source, bool _yul)
|
||||
{
|
||||
auto result = parse(_source, _yul);
|
||||
return boost::get<Block>(Disambiguator(*result.second, {})(*result.first));
|
||||
}
|
||||
|
||||
string dev::yul::test::format(string const& _source, bool _yul)
|
||||
string yul::test::format(string const& _source, bool _yul)
|
||||
{
|
||||
return assembly::AsmPrinter(_yul)(*parse(_source, _yul).first);
|
||||
return yul::AsmPrinter(_yul)(*parse(_source, _yul).first);
|
||||
}
|
||||
|
@ -34,26 +34,21 @@ class Error;
|
||||
using ErrorList = std::vector<std::shared_ptr<Error const>>;
|
||||
}
|
||||
|
||||
namespace dev
|
||||
{
|
||||
namespace solidity
|
||||
{
|
||||
namespace assembly
|
||||
namespace yul
|
||||
{
|
||||
struct AsmAnalysisInfo;
|
||||
}
|
||||
}
|
||||
|
||||
namespace yul
|
||||
{
|
||||
namespace test
|
||||
{
|
||||
|
||||
void printErrors(langutil::ErrorList const& _errors, langutil::Scanner const& _scanner);
|
||||
std::pair<std::shared_ptr<solidity::assembly::Block>, std::shared_ptr<solidity::assembly::AsmAnalysisInfo>>
|
||||
std::pair<std::shared_ptr<Block>, std::shared_ptr<AsmAnalysisInfo>>
|
||||
parse(std::string const& _source, bool _yul = true);
|
||||
solidity::assembly::Block disambiguate(std::string const& _source, bool _yul = true);
|
||||
Block disambiguate(std::string const& _source, bool _yul = true);
|
||||
std::string format(std::string const& _source, bool _yul = true);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user