aboutsummaryrefslogtreecommitdiffstats
path: root/ExpressionCompiler.h
diff options
context:
space:
mode:
authorChristian <c@ethdev.com>2015-02-25 22:14:22 +0800
committerChristian <c@ethdev.com>2015-02-25 22:41:19 +0800
commitcc31a7ab321a974cd81de2b539ec2bf7db2b2358 (patch)
treea4fb5238cb20e5caf479791f337315526f89e390 /ExpressionCompiler.h
parent7f3a544d2a089e38a21b1ce566060edb8fe9c2b2 (diff)
downloaddexon-solidity-cc31a7ab321a974cd81de2b539ec2bf7db2b2358.tar.gz
dexon-solidity-cc31a7ab321a974cd81de2b539ec2bf7db2b2358.tar.zst
dexon-solidity-cc31a7ab321a974cd81de2b539ec2bf7db2b2358.zip
LValue refactoring.
Diffstat (limited to 'ExpressionCompiler.h')
-rw-r--r--ExpressionCompiler.h108
1 files changed, 26 insertions, 82 deletions
diff --git a/ExpressionCompiler.h b/ExpressionCompiler.h
index 2eb8ca20..edb63ad9 100644
--- a/ExpressionCompiler.h
+++ b/ExpressionCompiler.h
@@ -27,6 +27,7 @@
#include <libdevcore/Common.h>
#include <libevmcore/SourceLocation.h>
#include <libsolidity/ASTVisitor.h>
+#include <libsolidity/LValue.h>
namespace dev {
namespace eth
@@ -50,22 +51,28 @@ class StaticStringType;
class ExpressionCompiler: private ASTConstVisitor
{
public:
- /// Compile the given @a _expression into the @a _context.
- static void compileExpression(CompilerContext& _context, Expression const& _expression, bool _optimize = false);
-
- /// Appends code to remove dirty higher order bits in case of an implicit promotion to a wider type.
- static void appendTypeConversion(CompilerContext& _context, Type const& _typeOnStack,
- Type const& _targetType, bool _cleanupNeeded = false);
/// Appends code for a State Variable accessor function
static void appendStateVariableAccessor(CompilerContext& _context, VariableDeclaration const& _varDecl, bool _optimize = false);
- /// Appends code for a State Variable Initialization function
- static void appendStateVariableInitialization(CompilerContext& _context, VariableDeclaration const& _varDecl, bool _optimize = false);
-
-private:
explicit ExpressionCompiler(CompilerContext& _compilerContext, bool _optimize = false):
- m_optimize(_optimize), m_context(_compilerContext), m_currentLValue(m_context) {}
+ m_optimize(_optimize), m_context(_compilerContext) {}
+
+ /// Compile the given @a _expression and leave its value on the stack.
+ void compile(Expression const& _expression);
+
+ /// Appends code to set a state variable to its initial value/expression.
+ void appendStateVariableInitialization(VariableDeclaration const& _varDecl);
+
+ /// Appends code for a State Variable accessor function
+ void appendStateVariableAccessor(VariableDeclaration const& _varDecl);
+
+ /// Appends an implicit or explicit type conversion. For now this comprises only erasing
+ /// higher-order bits (@see appendHighBitCleanup) when widening integer.
+ /// If @a _cleanupNeeded, high order bits cleanup is also done if no type conversion would be
+ /// necessary.
+ void appendTypeConversion(Type const& _typeOnStack, Type const& _targetType, bool _cleanupNeeded = false);
+private:
virtual bool visit(Assignment const& _assignment) override;
virtual bool visit(UnaryOperation const& _unaryOperation) override;
virtual bool visit(BinaryOperation const& _binaryOperation) override;
@@ -87,11 +94,6 @@ private:
void appendShiftOperatorCode(Token::Value _operator);
/// @}
- /// Appends an implicit or explicit type conversion. For now this comprises only erasing
- /// higher-order bits (@see appendHighBitCleanup) when widening integer.
- /// If @a _cleanupNeeded, high order bits cleanup is also done if no type conversion would be
- /// necessary.
- void appendTypeConversion(Type const& _typeOnStack, Type const& _targetType, bool _cleanupNeeded = false);
//// Appends code that cleans higher-order bits for integer types.
void appendHighBitsCleanup(IntegerType const& _typeOnStack);
@@ -111,75 +113,17 @@ private:
/// expected to be on the stack and is updated by this call.
void appendExpressionCopyToMemory(Type const& _expectedType, Expression const& _expression);
- /// Appends code for a State Variable accessor function
- void appendStateVariableAccessor(VariableDeclaration const& _varDecl);
-
- /// Appends code for a State Variable initialization
- void appendStateVariableInitialization(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
- * stores the base stack offset of the variable in @a m_baseStackOffset.
- */
- class LValue
- {
- public:
- enum class LValueType { None, Stack, Memory, Storage };
-
- explicit LValue(CompilerContext& _compilerContext): m_context(&_compilerContext) { reset(); }
- LValue(CompilerContext& _compilerContext, LValueType _type,
- std::shared_ptr<Type const> const& _dataType, unsigned _baseStackOffset = 0);
-
- /// Set type according to the declaration and retrieve the reference.
- /// @a _location is the current location
- void fromDeclaration(Declaration const& _declaration, SourceLocation const& _location);
-
- void reset() { m_type = LValueType::None; m_dataType.reset(); m_baseStackOffset = 0; m_size = 0; }
-
- bool isValid() const { return m_type != LValueType::None; }
- bool isInOnStack() const { return m_type == LValueType::Stack; }
- bool isInMemory() const { return m_type == LValueType::Memory; }
- bool isInStorage() const { return m_type == LValueType::Storage; }
-
- /// @returns true if this lvalue reference type occupies a slot on the stack.
- bool storesReferenceOnStack() const { return m_type == LValueType::Storage || m_type == LValueType::Memory; }
-
- /// Copies the value of the current lvalue to the top of the stack and, if @a _remove is true,
- /// also removes the reference from the stack (note that is does not reset the type to @a NONE).
- /// @a _location source location of the current expression, used for error reporting.
- void retrieveValue(SourceLocation const& _location, bool _remove = false) const;
- /// Moves a value from the stack to the lvalue. Removes the value if @a _move is true.
- /// @a _location is the source location of the expression that caused this operation.
- /// Stack pre: value [lvalue_ref]
- /// Stack post if !_move: value_of(lvalue_ref)
- void storeValue(Type const& _sourceType, SourceLocation const& _location = SourceLocation(), bool _move = false) const;
- /// Stores zero in the lvalue.
- /// @a _location is the source location of the requested operation
- void setToZero(SourceLocation const& _location = SourceLocation()) const;
- /// Convenience function to convert the stored reference to a value and reset type to NONE if
- /// the reference was not requested by @a _expression.
- void retrieveValueIfLValueNotRequested(Expression const& _expression);
-
- private:
- /// Convenience function to retrieve Value from Storage. Specific version of @ref retrieveValue
- void retrieveValueFromStorage(bool _remove = false) const;
- /// Copies from a byte array to a byte array in storage, both references on the stack.
- void copyByteArrayToStorage(ArrayType const& _targetType, ArrayType const& _sourceType) const;
-
- CompilerContext* m_context;
- LValueType m_type = LValueType::None;
- std::shared_ptr<Type const> m_dataType;
- /// If m_type is STACK, this is base stack offset (@see
- /// CompilerContext::getBaseStackOffsetOfVariable) of a local variable.
- unsigned m_baseStackOffset = 0;
- /// Size of the value of this lvalue on the stack or the storage.
- unsigned m_size = 0;
- };
+ /// Sets the current LValue to a new one (of the appropriate type) from the given declaration.
+ /// Also retrieves the value if it was not requested by @a _expression.
+ void setLValueFromDeclaration(Declaration const& _declaration, Expression const& _expression);
+ /// Sets the current LValue to a StorageItem holding the type of @a _expression. The reference is assumed
+ /// to be on the stack.
+ /// Also retrieves the value if it was not requested by @a _expression.
+ void setLValueToStorageItem(Expression const& _expression);
bool m_optimize;
CompilerContext& m_context;
- LValue m_currentLValue;
+ std::unique_ptr<LValue> m_currentLValue;
};