mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
IR generation for constants.
This commit is contained in:
@@ -202,11 +202,11 @@ string IRGenerator::generateGetter(VariableDeclaration const& _varDecl)
|
||||
|
||||
Type const* type = _varDecl.annotation().type;
|
||||
|
||||
solAssert(!_varDecl.isConstant(), "");
|
||||
solAssert(_varDecl.isStateVariable(), "");
|
||||
|
||||
if (auto const* mappingType = dynamic_cast<MappingType const*>(type))
|
||||
return m_context.functionCollector().createFunction(functionName, [&]() {
|
||||
solAssert(!_varDecl.isConstant(), "");
|
||||
pair<u256, unsigned> slot_offset = m_context.storageLocationOfVariable(_varDecl);
|
||||
solAssert(slot_offset.second == 0, "");
|
||||
FunctionType funType(_varDecl);
|
||||
@@ -268,6 +268,16 @@ string IRGenerator::generateGetter(VariableDeclaration const& _varDecl)
|
||||
("id", to_string(_varDecl.id()))
|
||||
.render();
|
||||
}
|
||||
else if (_varDecl.isConstant())
|
||||
return Whiskers(R"(
|
||||
function <functionName>() -> <ret> {
|
||||
<ret> := <constantValueFunction>()
|
||||
}
|
||||
)")
|
||||
("functionName", functionName)
|
||||
("constantValueFunction", IRGeneratorForStatements(m_context, m_utils).constantValueFunction(_varDecl))
|
||||
("ret", suffixedVariableNameList("ret_", 0, _varDecl.type()->sizeOnStack()))
|
||||
.render();
|
||||
else
|
||||
{
|
||||
pair<u256, unsigned> slot_offset = m_context.storageLocationOfVariable(_varDecl);
|
||||
|
||||
@@ -178,6 +178,28 @@ IRVariable IRGeneratorForStatements::evaluateExpression(Expression const& _expre
|
||||
return variable;
|
||||
}
|
||||
|
||||
string IRGeneratorForStatements::constantValueFunction(VariableDeclaration const& _constant)
|
||||
{
|
||||
string functionName = "constant_" + _constant.name() + "_" + to_string(_constant.id());
|
||||
return m_context.functionCollector().createFunction(functionName, [&] {
|
||||
Whiskers templ(R"(
|
||||
function <functionName>() -> <ret> {
|
||||
<code>
|
||||
<ret> := <value>
|
||||
}
|
||||
)");
|
||||
templ("functionName", functionName);
|
||||
IRGeneratorForStatements generator(m_context, m_utils);
|
||||
solAssert(_constant.value(), "");
|
||||
Type const& constantType = *_constant.type();
|
||||
templ("value", generator.evaluateExpression(*_constant.value(), constantType).commaSeparatedList());
|
||||
templ("code", generator.code());
|
||||
templ("ret", IRVariable("ret", constantType).commaSeparatedList());
|
||||
|
||||
return templ.render();
|
||||
});
|
||||
}
|
||||
|
||||
void IRGeneratorForStatements::endVisit(VariableDeclarationStatement const& _varDeclStatement)
|
||||
{
|
||||
if (Expression const* expression = _varDeclStatement.initialValue())
|
||||
@@ -1576,11 +1598,9 @@ void IRGeneratorForStatements::handleVariableReference(
|
||||
Expression const& _referencingExpression
|
||||
)
|
||||
{
|
||||
// TODO for the constant case, we have to be careful:
|
||||
// If the value is visited twice, `defineExpression` is called twice on
|
||||
// the same expression.
|
||||
solUnimplementedAssert(!_variable.isConstant(), "");
|
||||
if (_variable.isStateVariable() && _variable.immutable())
|
||||
if (_variable.isStateVariable() && _variable.isConstant())
|
||||
define(_referencingExpression) << constantValueFunction(_variable) << "()\n";
|
||||
else if (_variable.isStateVariable() && _variable.immutable())
|
||||
setLValue(_referencingExpression, IRLValue{
|
||||
*_variable.annotation().type,
|
||||
IRLValue::Immutable{&_variable}
|
||||
|
||||
@@ -54,6 +54,10 @@ public:
|
||||
/// Calculates expression's value and returns variable where it was stored
|
||||
IRVariable evaluateExpression(Expression const& _expression, Type const& _to);
|
||||
|
||||
/// @returns the name of a function that computes the value of the given constant
|
||||
/// and also generates the function.
|
||||
std::string constantValueFunction(VariableDeclaration const& _constant);
|
||||
|
||||
void endVisit(VariableDeclarationStatement const& _variableDeclaration) override;
|
||||
bool visit(Conditional const& _conditional) override;
|
||||
bool visit(Assignment const& _assignment) override;
|
||||
|
||||
Reference in New Issue
Block a user