mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Yul codegen for immutables.
This commit is contained in:
@@ -140,20 +140,21 @@ string IRGeneratorForStatements::code() const
|
||||
|
||||
void IRGeneratorForStatements::initializeStateVar(VariableDeclaration const& _varDecl)
|
||||
{
|
||||
solAssert(m_context.isStateVariable(_varDecl), "Must be a state variable.");
|
||||
solAssert(_varDecl.immutable() || m_context.isStateVariable(_varDecl), "Must be immutable or a state variable.");
|
||||
solAssert(!_varDecl.isConstant(), "");
|
||||
solAssert(!_varDecl.immutable(), "");
|
||||
if (_varDecl.value())
|
||||
{
|
||||
_varDecl.value()->accept(*this);
|
||||
writeToLValue(IRLValue{
|
||||
*_varDecl.annotation().type,
|
||||
IRLValue::Storage{
|
||||
util::toCompactHexWithPrefix(m_context.storageLocationOfVariable(_varDecl).first),
|
||||
m_context.storageLocationOfVariable(_varDecl).second
|
||||
}
|
||||
}, *_varDecl.value());
|
||||
}
|
||||
if (!_varDecl.value())
|
||||
return;
|
||||
|
||||
_varDecl.value()->accept(*this);
|
||||
writeToLValue(
|
||||
_varDecl.immutable() ?
|
||||
IRLValue{*_varDecl.annotation().type, IRLValue::Immutable{&_varDecl}} :
|
||||
IRLValue{*_varDecl.annotation().type, IRLValue::Storage{
|
||||
util::toCompactHexWithPrefix(m_context.storageLocationOfVariable(_varDecl).first),
|
||||
m_context.storageLocationOfVariable(_varDecl).second
|
||||
}},
|
||||
*_varDecl.value()
|
||||
);
|
||||
}
|
||||
|
||||
void IRGeneratorForStatements::initializeLocalVar(VariableDeclaration const& _varDecl)
|
||||
@@ -1517,8 +1518,12 @@ void IRGeneratorForStatements::handleVariableReference(
|
||||
// If the value is visited twice, `defineExpression` is called twice on
|
||||
// the same expression.
|
||||
solUnimplementedAssert(!_variable.isConstant(), "");
|
||||
solUnimplementedAssert(!_variable.immutable(), "");
|
||||
if (m_context.isLocalVariable(_variable))
|
||||
if (_variable.isStateVariable() && _variable.immutable())
|
||||
setLValue(_referencingExpression, IRLValue{
|
||||
*_variable.annotation().type,
|
||||
IRLValue::Immutable{&_variable}
|
||||
});
|
||||
else if (m_context.isLocalVariable(_variable))
|
||||
setLValue(_referencingExpression, IRLValue{
|
||||
*_variable.annotation().type,
|
||||
IRLValue::Stack{m_context.localVariable(_variable)}
|
||||
@@ -1939,6 +1944,18 @@ void IRGeneratorForStatements::writeToLValue(IRLValue const& _lvalue, IRVariable
|
||||
}
|
||||
},
|
||||
[&](IRLValue::Stack const& _stack) { assign(_stack.variable, _value); },
|
||||
[&](IRLValue::Immutable const& _immutable)
|
||||
{
|
||||
solUnimplementedAssert(_lvalue.type.isValueType(), "");
|
||||
solUnimplementedAssert(_lvalue.type.sizeOnStack() == 1, "");
|
||||
solAssert(_lvalue.type == *_immutable.variable->type(), "");
|
||||
size_t memOffset = m_context.immutableMemoryOffset(*_immutable.variable);
|
||||
|
||||
IRVariable prepared(m_context.newYulVariable(), _lvalue.type);
|
||||
define(prepared, _value);
|
||||
|
||||
m_code << "mstore(" << to_string(memOffset) << ", " << prepared.commaSeparatedList() << ")\n";
|
||||
},
|
||||
[&](IRLValue::Tuple const& _tuple) {
|
||||
auto components = std::move(_tuple.components);
|
||||
for (size_t i = 0; i < components.size(); i++)
|
||||
@@ -1994,6 +2011,12 @@ IRVariable IRGeneratorForStatements::readFromLValue(IRLValue const& _lvalue)
|
||||
[&](IRLValue::Stack const& _stack) {
|
||||
define(result, _stack.variable);
|
||||
},
|
||||
[&](IRLValue::Immutable const& _immutable) {
|
||||
solUnimplementedAssert(_lvalue.type.isValueType(), "");
|
||||
solUnimplementedAssert(_lvalue.type.sizeOnStack() == 1, "");
|
||||
solAssert(_lvalue.type == *_immutable.variable->type(), "");
|
||||
define(result) << "loadimmutable(\"" << to_string(_immutable.variable->id()) << "\")\n";
|
||||
},
|
||||
[&](IRLValue::Tuple const&) {
|
||||
solAssert(false, "Attempted to read from tuple lvalue.");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user