diff options
author | Lefteris Karapetsas <lefteris@refu.co> | 2015-01-27 01:16:47 +0800 |
---|---|---|
committer | Lefteris Karapetsas <lefteris@refu.co> | 2015-01-29 04:46:16 +0800 |
commit | 6e793b24996610c5a88a0aafb9fad365d9f12b00 (patch) | |
tree | 16887c6be06407418adbd88a7473ad7db4dd8de5 | |
parent | 3ec6c0b1cbe1be0a95f711ce74b0e360fabdaa96 (diff) | |
download | dexon-solidity-6e793b24996610c5a88a0aafb9fad365d9f12b00.tar dexon-solidity-6e793b24996610c5a88a0aafb9fad365d9f12b00.tar.gz dexon-solidity-6e793b24996610c5a88a0aafb9fad365d9f12b00.tar.bz2 dexon-solidity-6e793b24996610c5a88a0aafb9fad365d9f12b00.tar.lz dexon-solidity-6e793b24996610c5a88a0aafb9fad365d9f12b00.tar.xz dexon-solidity-6e793b24996610c5a88a0aafb9fad365d9f12b00.tar.zst dexon-solidity-6e793b24996610c5a88a0aafb9fad365d9f12b00.zip |
Work on ExpressionCompiler preparing for Accessors from storage
-rw-r--r-- | ExpressionCompiler.cpp | 55 | ||||
-rw-r--r-- | ExpressionCompiler.h | 8 |
2 files changed, 44 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()) diff --git a/ExpressionCompiler.h b/ExpressionCompiler.h index 8f784fde..7189bef9 100644 --- a/ExpressionCompiler.h +++ b/ExpressionCompiler.h @@ -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 |