Accessors for immutable variables.

This commit is contained in:
chriseth 2020-04-02 17:13:31 +02:00
parent bdcfd71f34
commit d7a39c86ce
5 changed files with 49 additions and 7 deletions

View File

@ -566,8 +566,6 @@ bool ContractCompiler::visit(VariableDeclaration const& _variableDeclaration)
if (_variableDeclaration.isConstant())
ExpressionCompiler(m_context, m_optimiserSettings.runOrderLiterals)
.appendConstStateVariableAccessor(_variableDeclaration);
else if (_variableDeclaration.immutable())
solUnimplementedAssert(false, "");
else
ExpressionCompiler(m_context, m_optimiserSettings.runOrderLiterals)
.appendStateVariableAccessor(_variableDeclaration);

View File

@ -91,16 +91,22 @@ void ExpressionCompiler::appendConstStateVariableAccessor(VariableDeclaration co
void ExpressionCompiler::appendStateVariableAccessor(VariableDeclaration const& _varDecl)
{
solAssert(!_varDecl.isConstant() && !_varDecl.immutable(), "");
solAssert(!_varDecl.isConstant(), "");
CompilerContext::LocationSetter locationSetter(m_context, _varDecl);
FunctionType accessorType(_varDecl);
TypePointers paramTypes = accessorType.parameterTypes();
if (_varDecl.immutable())
solAssert(paramTypes.empty(), "");
m_context.adjustStackOffset(1 + CompilerUtils::sizeOnStack(paramTypes));
// retrieve the position of the variable
auto const& location = m_context.storageLocationOfVariable(_varDecl);
m_context << location.first << u256(location.second);
if (!_varDecl.immutable())
{
// retrieve the position of the variable
auto const& location = m_context.storageLocationOfVariable(_varDecl);
m_context << location.first << u256(location.second);
}
TypePointer returnType = _varDecl.annotation().type;
@ -182,6 +188,7 @@ void ExpressionCompiler::appendStateVariableAccessor(VariableDeclaration const&
solAssert(returnTypes.size() >= 1, "");
if (StructType const* structType = dynamic_cast<StructType const*>(returnType))
{
solAssert(!_varDecl.immutable(), "");
// remove offset
m_context << Instruction::POP;
auto const& names = accessorType.returnParameterNames();
@ -208,7 +215,10 @@ void ExpressionCompiler::appendStateVariableAccessor(VariableDeclaration const&
{
// simple value or array
solAssert(returnTypes.size() == 1, "");
StorageItem(m_context, *returnType).retrieveValue(SourceLocation(), true);
if (_varDecl.immutable())
ImmutableItem(m_context, _varDecl).retrieveValue(SourceLocation());
else
StorageItem(m_context, *returnType).retrieveValue(SourceLocation(), true);
utils().convertType(*returnType, *returnTypes.front());
retSizeOnStack = returnTypes.front()->sizeOnStack();
}

View File

@ -0,0 +1,12 @@
contract C {
function() external returns (uint, uint) immutable public x = this.f;
function f() external pure returns (uint, uint) {
return (1, 2);
}
function test() external returns (uint, uint) {
return this.x()();
}
}
// ----
// test() -> 1, 2

View File

@ -0,0 +1,5 @@
contract C {
uint immutable public x = 1;
}
// ----
// x() -> 1

View File

@ -0,0 +1,17 @@
contract A {
uint immutable public x = 1;
uint public y;
constructor() public {
y = this.x();
}
}
contract C {
function f() public returns (bool) {
try new A() { return false; }
catch { return true; }
}
}
// ====
// EVMVersion: >=tangerineWhistle
// ----
// f() -> true