diff options
Diffstat (limited to 'ExpressionCompiler.cpp')
-rw-r--r-- | ExpressionCompiler.cpp | 55 |
1 files changed, 36 insertions, 19 deletions
diff --git a/ExpressionCompiler.cpp b/ExpressionCompiler.cpp index bd8c8653..450cc2fe 100644 --- a/ExpressionCompiler.cpp +++ b/ExpressionCompiler.cpp @@ -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()) |