mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Move generation of builtin functions to helper.
This commit is contained in:
parent
7de150924c
commit
9a387380b3
@ -35,64 +35,98 @@ using namespace std;
|
|||||||
using namespace dev;
|
using namespace dev;
|
||||||
using namespace yul;
|
using namespace yul;
|
||||||
|
|
||||||
EVMDialect::EVMDialect(AsmFlavour _flavour, bool _objectAccess, langutil::EVMVersion _evmVersion):
|
namespace
|
||||||
Dialect{_flavour}, m_objectAccess(_objectAccess), m_evmVersion(_evmVersion)
|
|
||||||
{
|
{
|
||||||
// The EVM instructions will be moved to builtins at some point.
|
pair<YulString, BuiltinFunctionForEVM> createFunction(
|
||||||
if (!m_objectAccess)
|
string _name,
|
||||||
return;
|
size_t _params,
|
||||||
|
size_t _returns,
|
||||||
|
bool _movable,
|
||||||
|
bool _sideEffectFree,
|
||||||
|
bool _literalArguments,
|
||||||
|
std::function<void(FunctionCall const&, AbstractAssembly&, BuiltinContext&, std::function<void()>)> _generateCode
|
||||||
|
)
|
||||||
|
{
|
||||||
|
YulString name{std::move(_name)};
|
||||||
|
BuiltinFunctionForEVM f;
|
||||||
|
f.name = name;
|
||||||
|
f.parameters.resize(_params);
|
||||||
|
f.returns.resize(_returns);
|
||||||
|
f.movable = _movable;
|
||||||
|
f.literalArguments = _literalArguments;
|
||||||
|
f.sideEffectFree = _sideEffectFree;
|
||||||
|
f.generateCode = std::move(_generateCode);
|
||||||
|
return {name, f};
|
||||||
|
}
|
||||||
|
|
||||||
addFunction("datasize", 1, 1, true, true, true, [](
|
map<YulString, BuiltinFunctionForEVM> createBuiltins(langutil::EVMVersion, bool _objectAccess)
|
||||||
FunctionCall const& _call,
|
{
|
||||||
AbstractAssembly& _assembly,
|
map<YulString, BuiltinFunctionForEVM> builtins;
|
||||||
BuiltinContext& _context,
|
if (_objectAccess)
|
||||||
std::function<void()>
|
{
|
||||||
) {
|
builtins.emplace(createFunction("datasize", 1, 1, true, true, true, [](
|
||||||
yulAssert(_context.currentObject, "No object available.");
|
FunctionCall const& _call,
|
||||||
yulAssert(_call.arguments.size() == 1, "");
|
AbstractAssembly& _assembly,
|
||||||
Expression const& arg = _call.arguments.front();
|
BuiltinContext& _context,
|
||||||
YulString dataName = boost::get<Literal>(arg).value;
|
function<void()>
|
||||||
if (_context.currentObject->name == dataName)
|
) {
|
||||||
_assembly.appendAssemblySize();
|
yulAssert(_context.currentObject, "No object available.");
|
||||||
else
|
yulAssert(_call.arguments.size() == 1, "");
|
||||||
{
|
Expression const& arg = _call.arguments.front();
|
||||||
yulAssert(
|
YulString dataName = boost::get<Literal>(arg).value;
|
||||||
_context.subIDs.count(dataName) != 0,
|
if (_context.currentObject->name == dataName)
|
||||||
"Could not find assembly object <" + dataName.str() + ">."
|
_assembly.appendAssemblySize();
|
||||||
);
|
else
|
||||||
_assembly.appendDataSize(_context.subIDs.at(dataName));
|
{
|
||||||
}
|
yulAssert(
|
||||||
});
|
_context.subIDs.count(dataName) != 0,
|
||||||
addFunction("dataoffset", 1, 1, true, true, true, [](
|
"Could not find assembly object <" + dataName.str() + ">."
|
||||||
FunctionCall const& _call,
|
);
|
||||||
AbstractAssembly& _assembly,
|
_assembly.appendDataSize(_context.subIDs.at(dataName));
|
||||||
BuiltinContext& _context,
|
}
|
||||||
std::function<void()>
|
}));
|
||||||
) {
|
builtins.emplace(createFunction("dataoffset", 1, 1, true, true, true, [](
|
||||||
yulAssert(_context.currentObject, "No object available.");
|
FunctionCall const& _call,
|
||||||
yulAssert(_call.arguments.size() == 1, "");
|
AbstractAssembly& _assembly,
|
||||||
Expression const& arg = _call.arguments.front();
|
BuiltinContext& _context,
|
||||||
YulString dataName = boost::get<Literal>(arg).value;
|
std::function<void()>
|
||||||
if (_context.currentObject->name == dataName)
|
) {
|
||||||
_assembly.appendConstant(0);
|
yulAssert(_context.currentObject, "No object available.");
|
||||||
else
|
yulAssert(_call.arguments.size() == 1, "");
|
||||||
{
|
Expression const& arg = _call.arguments.front();
|
||||||
yulAssert(
|
YulString dataName = boost::get<Literal>(arg).value;
|
||||||
_context.subIDs.count(dataName) != 0,
|
if (_context.currentObject->name == dataName)
|
||||||
"Could not find assembly object <" + dataName.str() + ">."
|
_assembly.appendConstant(0);
|
||||||
);
|
else
|
||||||
_assembly.appendDataOffset(_context.subIDs.at(dataName));
|
{
|
||||||
}
|
yulAssert(
|
||||||
});
|
_context.subIDs.count(dataName) != 0,
|
||||||
addFunction("datacopy", 3, 0, false, false, false, [](
|
"Could not find assembly object <" + dataName.str() + ">."
|
||||||
FunctionCall const&,
|
);
|
||||||
AbstractAssembly& _assembly,
|
_assembly.appendDataOffset(_context.subIDs.at(dataName));
|
||||||
BuiltinContext&,
|
}
|
||||||
std::function<void()> _visitArguments
|
}));
|
||||||
) {
|
builtins.emplace(createFunction("datacopy", 3, 0, false, false, false, [](
|
||||||
_visitArguments();
|
FunctionCall const&,
|
||||||
_assembly.appendInstruction(dev::eth::Instruction::CODECOPY);
|
AbstractAssembly& _assembly,
|
||||||
});
|
BuiltinContext&,
|
||||||
|
std::function<void()> _visitArguments
|
||||||
|
) {
|
||||||
|
_visitArguments();
|
||||||
|
_assembly.appendInstruction(dev::eth::Instruction::CODECOPY);
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
return builtins;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
EVMDialect::EVMDialect(AsmFlavour _flavour, bool _objectAccess, langutil::EVMVersion _evmVersion):
|
||||||
|
Dialect{_flavour},
|
||||||
|
m_objectAccess(_objectAccess),
|
||||||
|
m_evmVersion(_evmVersion),
|
||||||
|
m_functions(createBuiltins(_evmVersion, _objectAccess))
|
||||||
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
BuiltinFunctionForEVM const* EVMDialect::builtin(YulString _name) const
|
BuiltinFunctionForEVM const* EVMDialect::builtin(YulString _name) const
|
||||||
@ -123,24 +157,3 @@ shared_ptr<yul::EVMDialect> EVMDialect::yulForEVM(langutil::EVMVersion _version)
|
|||||||
{
|
{
|
||||||
return make_shared<EVMDialect>(AsmFlavour::Yul, false, _version);
|
return make_shared<EVMDialect>(AsmFlavour::Yul, false, _version);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EVMDialect::addFunction(
|
|
||||||
string _name,
|
|
||||||
size_t _params,
|
|
||||||
size_t _returns,
|
|
||||||
bool _movable,
|
|
||||||
bool _sideEffectFree,
|
|
||||||
bool _literalArguments,
|
|
||||||
std::function<void(FunctionCall const&, AbstractAssembly&, BuiltinContext&, std::function<void()>)> _generateCode
|
|
||||||
)
|
|
||||||
{
|
|
||||||
YulString name{std::move(_name)};
|
|
||||||
BuiltinFunctionForEVM& f = m_functions[name];
|
|
||||||
f.name = name;
|
|
||||||
f.parameters.resize(_params);
|
|
||||||
f.returns.resize(_returns);
|
|
||||||
f.movable = _movable;
|
|
||||||
f.sideEffectFree = _sideEffectFree;
|
|
||||||
f.literalArguments = _literalArguments;
|
|
||||||
f.generateCode = std::move(_generateCode);
|
|
||||||
}
|
|
||||||
|
@ -76,18 +76,8 @@ struct EVMDialect: public Dialect
|
|||||||
bool providesObjectAccess() const { return m_objectAccess; }
|
bool providesObjectAccess() const { return m_objectAccess; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void addFunction(
|
bool const m_objectAccess;
|
||||||
std::string _name,
|
langutil::EVMVersion const m_evmVersion;
|
||||||
size_t _params,
|
|
||||||
size_t _returns,
|
|
||||||
bool _movable,
|
|
||||||
bool _sideEffectFree,
|
|
||||||
bool _literalArguments,
|
|
||||||
std::function<void(FunctionCall const&, AbstractAssembly&, BuiltinContext&, std::function<void()>)> _generateCode
|
|
||||||
);
|
|
||||||
|
|
||||||
bool m_objectAccess;
|
|
||||||
langutil::EVMVersion m_evmVersion;
|
|
||||||
std::map<YulString, BuiltinFunctionForEVM> m_functions;
|
std::map<YulString, BuiltinFunctionForEVM> m_functions;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user