mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Move memory load and store functions to the dialect.
This commit is contained in:
parent
48f620fb50
commit
f3c2d6cfdc
@ -72,6 +72,9 @@ struct Dialect: boost::noncopyable
|
|||||||
virtual BuiltinFunction const* equalityFunction(YulString /* _type */) const { return nullptr; }
|
virtual BuiltinFunction const* equalityFunction(YulString /* _type */) const { return nullptr; }
|
||||||
virtual BuiltinFunction const* booleanNegationFunction() const { return nullptr; }
|
virtual BuiltinFunction const* booleanNegationFunction() const { return nullptr; }
|
||||||
|
|
||||||
|
virtual BuiltinFunction const* memoryStoreFunction(YulString /* _type */) const { return nullptr; }
|
||||||
|
virtual BuiltinFunction const* memoryLoadFunction(YulString /* _type */) const { return nullptr; }
|
||||||
|
|
||||||
/// Check whether the given type is legal for the given literal value.
|
/// Check whether the given type is legal for the given literal value.
|
||||||
/// Should only be called if the type exists in the dialect at all.
|
/// Should only be called if the type exists in the dialect at all.
|
||||||
virtual bool validTypeForLiteral(LiteralKind _kind, YulString _value, YulString _type) const;
|
virtual bool validTypeForLiteral(LiteralKind _kind, YulString _value, YulString _type) const;
|
||||||
|
@ -73,6 +73,8 @@ struct EVMDialect: public Dialect
|
|||||||
BuiltinFunctionForEVM const* discardFunction(YulString /*_type*/) const override { return builtin("pop"_yulstring); }
|
BuiltinFunctionForEVM const* discardFunction(YulString /*_type*/) const override { return builtin("pop"_yulstring); }
|
||||||
BuiltinFunctionForEVM const* equalityFunction(YulString /*_type*/) const override { return builtin("eq"_yulstring); }
|
BuiltinFunctionForEVM const* equalityFunction(YulString /*_type*/) const override { return builtin("eq"_yulstring); }
|
||||||
BuiltinFunctionForEVM const* booleanNegationFunction() const override { return builtin("iszero"_yulstring); }
|
BuiltinFunctionForEVM const* booleanNegationFunction() const override { return builtin("iszero"_yulstring); }
|
||||||
|
BuiltinFunctionForEVM const* memoryStoreFunction(YulString /*_type*/) const override { return builtin("mstore"_yulstring); }
|
||||||
|
BuiltinFunctionForEVM const* memoryLoadFunction(YulString /*_type*/) const override { return builtin("mload"_yulstring); }
|
||||||
|
|
||||||
static EVMDialect const& strictAssemblyForEVM(langutil::EVMVersion _version);
|
static EVMDialect const& strictAssemblyForEVM(langutil::EVMVersion _version);
|
||||||
static EVMDialect const& strictAssemblyForEVMObjects(langutil::EVMVersion _version);
|
static EVMDialect const& strictAssemblyForEVMObjects(langutil::EVMVersion _version);
|
||||||
|
@ -30,15 +30,18 @@ using namespace solidity::yul;
|
|||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
vector<Statement> generateMemoryStore(
|
vector<Statement> generateMemoryStore(
|
||||||
|
Dialect const& _dialect,
|
||||||
langutil::SourceLocation const& _loc,
|
langutil::SourceLocation const& _loc,
|
||||||
YulString _mpos,
|
YulString _mpos,
|
||||||
Expression _value
|
Expression _value
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
BuiltinFunction const* memoryStoreFunction = _dialect.memoryStoreFunction(_dialect.defaultType);
|
||||||
|
yulAssert(memoryStoreFunction, "");
|
||||||
vector<Statement> result;
|
vector<Statement> result;
|
||||||
result.emplace_back(ExpressionStatement{_loc, FunctionCall{
|
result.emplace_back(ExpressionStatement{_loc, FunctionCall{
|
||||||
_loc,
|
_loc,
|
||||||
Identifier{_loc, "mstore"_yulstring},
|
Identifier{_loc, memoryStoreFunction->name},
|
||||||
{
|
{
|
||||||
Literal{_loc, LiteralKind::Number, _mpos, {}},
|
Literal{_loc, LiteralKind::Number, _mpos, {}},
|
||||||
std::move(_value)
|
std::move(_value)
|
||||||
@ -66,6 +69,7 @@ StackToMemoryMover::StackToMemoryMover(
|
|||||||
map<YulString, map<YulString, uint64_t>> const& _memorySlots,
|
map<YulString, map<YulString, uint64_t>> const& _memorySlots,
|
||||||
uint64_t _numRequiredSlots
|
uint64_t _numRequiredSlots
|
||||||
):
|
):
|
||||||
|
m_context(_context),
|
||||||
m_reservedMemory(std::move(_reservedMemory)),
|
m_reservedMemory(std::move(_reservedMemory)),
|
||||||
m_memorySlots(_memorySlots),
|
m_memorySlots(_memorySlots),
|
||||||
m_numRequiredSlots(_numRequiredSlots),
|
m_numRequiredSlots(_numRequiredSlots),
|
||||||
@ -120,6 +124,7 @@ void StackToMemoryMover::operator()(Block& _block)
|
|||||||
) -> std::vector<Statement> {
|
) -> std::vector<Statement> {
|
||||||
if (_variables.size() == 1)
|
if (_variables.size() == 1)
|
||||||
return generateMemoryStore(
|
return generateMemoryStore(
|
||||||
|
m_context.dialect,
|
||||||
_loc,
|
_loc,
|
||||||
memoryOffset(_variables.front().name),
|
memoryOffset(_variables.front().name),
|
||||||
_value ? *std::move(_value) : Literal{_loc, LiteralKind::Number, "0"_yulstring, {}}
|
_value ? *std::move(_value) : Literal{_loc, LiteralKind::Number, "0"_yulstring, {}}
|
||||||
@ -134,7 +139,12 @@ void StackToMemoryMover::operator()(Block& _block)
|
|||||||
tempDecl.variables.emplace_back(TypedName{var.location, tempVarName, {}});
|
tempDecl.variables.emplace_back(TypedName{var.location, tempVarName, {}});
|
||||||
|
|
||||||
if (m_currentFunctionMemorySlots->count(var.name))
|
if (m_currentFunctionMemorySlots->count(var.name))
|
||||||
memoryAssignments += generateMemoryStore(_loc, memoryOffset(var.name), Identifier{_loc, tempVarName});
|
memoryAssignments += generateMemoryStore(
|
||||||
|
m_context.dialect,
|
||||||
|
_loc,
|
||||||
|
memoryOffset(var.name),
|
||||||
|
Identifier{_loc, tempVarName}
|
||||||
|
);
|
||||||
else if constexpr (std::is_same_v<std::decay_t<decltype(var)>, Identifier>)
|
else if constexpr (std::is_same_v<std::decay_t<decltype(var)>, Identifier>)
|
||||||
variableAssignments.emplace_back(Assignment{
|
variableAssignments.emplace_back(Assignment{
|
||||||
_loc, { Identifier{var.location, var.name} },
|
_loc, { Identifier{var.location, var.name} },
|
||||||
@ -196,10 +206,12 @@ void StackToMemoryMover::visit(Expression& _expression)
|
|||||||
identifier && m_currentFunctionMemorySlots && m_currentFunctionMemorySlots->count(identifier->name)
|
identifier && m_currentFunctionMemorySlots && m_currentFunctionMemorySlots->count(identifier->name)
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
BuiltinFunction const* memoryLoadFunction = m_context.dialect.memoryLoadFunction(m_context.dialect.defaultType);
|
||||||
|
yulAssert(memoryLoadFunction, "");
|
||||||
langutil::SourceLocation loc = identifier->location;
|
langutil::SourceLocation loc = identifier->location;
|
||||||
_expression = FunctionCall{
|
_expression = FunctionCall{
|
||||||
loc,
|
loc,
|
||||||
Identifier{loc, "mload"_yulstring}, {
|
Identifier{loc, memoryLoadFunction->name}, {
|
||||||
Literal{
|
Literal{
|
||||||
loc,
|
loc,
|
||||||
LiteralKind::Number,
|
LiteralKind::Number,
|
||||||
|
@ -109,6 +109,8 @@ private:
|
|||||||
|
|
||||||
/// @returns a YulString containing the memory offset to be assigned to @a _variable as number literal.
|
/// @returns a YulString containing the memory offset to be assigned to @a _variable as number literal.
|
||||||
YulString memoryOffset(YulString _variable);
|
YulString memoryOffset(YulString _variable);
|
||||||
|
|
||||||
|
OptimiserStepContext& m_context;
|
||||||
u256 m_reservedMemory;
|
u256 m_reservedMemory;
|
||||||
std::map<YulString, std::map<YulString, uint64_t>> const& m_memorySlots;
|
std::map<YulString, std::map<YulString, uint64_t>> const& m_memorySlots;
|
||||||
uint64_t m_numRequiredSlots = 0;
|
uint64_t m_numRequiredSlots = 0;
|
||||||
|
Loading…
Reference in New Issue
Block a user