mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Work on ExpressionCompiler preparing for Accessors from storage
This commit is contained in:
parent
3ec6c0b1cb
commit
6e793b2499
@ -789,6 +789,13 @@ unsigned ExpressionCompiler::appendArgumentCopyToMemory(TypePointers const& _typ
|
||||
return length;
|
||||
}
|
||||
|
||||
void ExpressionCompiler::appendStateVariableAccessor(VariableDeclaration const* _varDecl)
|
||||
{
|
||||
m_currentLValue.fromStateVariable(*_varDecl, _varDecl->getType());
|
||||
// TODO
|
||||
// m_currentLValue.retrieveValueFromStorage();
|
||||
}
|
||||
|
||||
ExpressionCompiler::LValue::LValue(CompilerContext& _compilerContext, LValueType _type, Type const& _dataType,
|
||||
unsigned _baseStackOffset):
|
||||
m_context(&_compilerContext), m_type(_type), m_baseStackOffset(_baseStackOffset)
|
||||
@ -816,21 +823,7 @@ void ExpressionCompiler::LValue::retrieveValue(Expression const& _expression, bo
|
||||
break;
|
||||
}
|
||||
case STORAGE:
|
||||
if (!_expression.getType()->isValueType())
|
||||
break; // no distinction between value and reference for non-value types
|
||||
if (!_remove)
|
||||
*m_context << eth::Instruction::DUP1;
|
||||
if (m_size == 1)
|
||||
*m_context << eth::Instruction::SLOAD;
|
||||
else
|
||||
for (unsigned i = 0; i < m_size; ++i)
|
||||
{
|
||||
*m_context << eth::Instruction::DUP1 << eth::Instruction::SLOAD << eth::Instruction::SWAP1;
|
||||
if (i + 1 < m_size)
|
||||
*m_context << u256(1) << eth::Instruction::ADD;
|
||||
else
|
||||
*m_context << eth::Instruction::POP;
|
||||
}
|
||||
retrieveValueFromStorage(_expression, _remove);
|
||||
break;
|
||||
case MEMORY:
|
||||
if (!_expression.getType()->isValueType())
|
||||
@ -845,6 +838,25 @@ void ExpressionCompiler::LValue::retrieveValue(Expression const& _expression, bo
|
||||
}
|
||||
}
|
||||
|
||||
void ExpressionCompiler::LValue::retrieveValueFromStorage(Expression const& _expression, bool _remove) const
|
||||
{
|
||||
if (!_expression.getType()->isValueType())
|
||||
return; // no distinction between value and reference for non-value types
|
||||
if (!_remove)
|
||||
*m_context << eth::Instruction::DUP1;
|
||||
if (m_size == 1)
|
||||
*m_context << eth::Instruction::SLOAD;
|
||||
else
|
||||
for (unsigned i = 0; i < m_size; ++i)
|
||||
{
|
||||
*m_context << eth::Instruction::DUP1 << eth::Instruction::SLOAD << eth::Instruction::SWAP1;
|
||||
if (i + 1 < m_size)
|
||||
*m_context << u256(1) << eth::Instruction::ADD;
|
||||
else
|
||||
*m_context << eth::Instruction::POP;
|
||||
}
|
||||
}
|
||||
|
||||
void ExpressionCompiler::LValue::storeValue(Expression const& _expression, bool _move) const
|
||||
{
|
||||
switch (m_type)
|
||||
@ -951,6 +963,14 @@ void ExpressionCompiler::LValue::retrieveValueIfLValueNotRequested(Expression co
|
||||
}
|
||||
}
|
||||
|
||||
void ExpressionCompiler::LValue::fromStateVariable(Declaration const& _varDecl, std::shared_ptr<Type const> const& _type)
|
||||
{
|
||||
m_type = STORAGE;
|
||||
solAssert(_type->getStorageSize() <= numeric_limits<unsigned>::max(), "The storage size of " + _type->toString() + " should fit in an unsigned");
|
||||
*m_context << m_context->getStorageLocationOfVariable(_varDecl);
|
||||
m_size = unsigned(_type->getStorageSize());
|
||||
}
|
||||
|
||||
void ExpressionCompiler::LValue::fromIdentifier(Identifier const& _identifier, Declaration const& _declaration)
|
||||
{
|
||||
if (m_context->isLocalVariable(&_declaration))
|
||||
@ -961,10 +981,7 @@ void ExpressionCompiler::LValue::fromIdentifier(Identifier const& _identifier, D
|
||||
}
|
||||
else if (m_context->isStateVariable(&_declaration))
|
||||
{
|
||||
m_type = STORAGE;
|
||||
solAssert(_identifier.getType()->getStorageSize() <= numeric_limits<unsigned>::max(), "The storage size of " + _identifier.getType()->toString() + " should fit in unsigned");
|
||||
m_size = unsigned(_identifier.getType()->getStorageSize());
|
||||
*m_context << m_context->getStorageLocationOfVariable(_declaration);
|
||||
fromStateVariable(_declaration, _identifier.getType());
|
||||
}
|
||||
else
|
||||
BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_sourceLocation(_identifier.getLocation())
|
||||
|
@ -95,6 +95,9 @@ private:
|
||||
unsigned appendArgumentCopyToMemory(TypePointers const& _functionType, std::vector<ASTPointer<Expression const>> const& _arguments,
|
||||
unsigned _memoryOffset = 0);
|
||||
|
||||
/// Appends code for a State Variable accessor function
|
||||
void appendStateVariableAccessor(VariableDeclaration const* _varDecl);
|
||||
|
||||
/**
|
||||
* Helper class to store and retrieve lvalues to and from various locations.
|
||||
* All types except STACK store a reference in a slot on the stack, STACK just
|
||||
@ -111,6 +114,8 @@ private:
|
||||
/// Set type according to the declaration and retrieve the reference.
|
||||
/// @a _expression is the current expression
|
||||
void fromIdentifier(Identifier const& _identifier, Declaration const& _declaration);
|
||||
/// Convenience function to set type for a state variable and retrieve the reference
|
||||
void fromStateVariable(Declaration const& _varDecl, std::shared_ptr<Type const> const& _type);
|
||||
void reset() { m_type = NONE; m_baseStackOffset = 0; m_size = 0; }
|
||||
|
||||
bool isValid() const { return m_type != NONE; }
|
||||
@ -125,6 +130,9 @@ private:
|
||||
/// also removes the reference from the stack (note that is does not reset the type to @a NONE).
|
||||
/// @a _expression is the current expression, used for error reporting.
|
||||
void retrieveValue(Expression const& _expression, bool _remove = false) const;
|
||||
/// Convenience function to retrive Value from Storage. Specific version of
|
||||
/// @ref retrieveValue
|
||||
void retrieveValueFromStorage(Expression const& _expression, bool _remove = false) const;
|
||||
/// Stores a value (from the stack directly beneath the reference, which is assumed to
|
||||
/// be on the top of the stack, if any) in the lvalue and removes the reference.
|
||||
/// Also removes the stored value from the stack if @a _move is
|
||||
|
Loading…
Reference in New Issue
Block a user