aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGav Wood <g@ethdev.com>2015-02-04 00:47:46 +0800
committerGav Wood <g@ethdev.com>2015-02-04 00:47:46 +0800
commit61c701b9ff6e7fdca0ffe91937d2e6a4cd20f7c4 (patch)
treefc7a3e83d2b6d313643402699c37925393d65156
parentadce36ff583389819638218e2a11c0887b35282c (diff)
parent8cd3d4b4b7a440815229288d853b6ed81ba4eb43 (diff)
downloaddexon-solidity-61c701b9ff6e7fdca0ffe91937d2e6a4cd20f7c4.tar
dexon-solidity-61c701b9ff6e7fdca0ffe91937d2e6a4cd20f7c4.tar.gz
dexon-solidity-61c701b9ff6e7fdca0ffe91937d2e6a4cd20f7c4.tar.bz2
dexon-solidity-61c701b9ff6e7fdca0ffe91937d2e6a4cd20f7c4.tar.lz
dexon-solidity-61c701b9ff6e7fdca0ffe91937d2e6a4cd20f7c4.tar.xz
dexon-solidity-61c701b9ff6e7fdca0ffe91937d2e6a4cd20f7c4.tar.zst
dexon-solidity-61c701b9ff6e7fdca0ffe91937d2e6a4cd20f7c4.zip
Merge pull request #922 from LefterisJP/sol_AccessorsMapping
Sol state variable accessors for mapping
-rw-r--r--Compiler.cpp4
-rw-r--r--ExpressionCompiler.cpp49
-rw-r--r--ExpressionCompiler.h4
-rw-r--r--Types.cpp23
4 files changed, 63 insertions, 17 deletions
diff --git a/Compiler.cpp b/Compiler.cpp
index 3c46d455..389f826b 100644
--- a/Compiler.cpp
+++ b/Compiler.cpp
@@ -240,10 +240,6 @@ bool Compiler::visit(VariableDeclaration const& _variableDeclaration)
m_context << m_context.getFunctionEntryLabel(_variableDeclaration);
ExpressionCompiler::appendStateVariableAccessor(m_context, _variableDeclaration);
- unsigned sizeOnStack = _variableDeclaration.getType()->getSizeOnStack();
- solAssert(sizeOnStack <= 15, "Stack too deep.");
- m_context << eth::dupInstruction(sizeOnStack + 1) << eth::Instruction::JUMP;
-
return false;
}
diff --git a/ExpressionCompiler.cpp b/ExpressionCompiler.cpp
index 7d58ea2e..45e0e80b 100644
--- a/ExpressionCompiler.cpp
+++ b/ExpressionCompiler.cpp
@@ -22,6 +22,7 @@
#include <utility>
#include <numeric>
+#include <boost/range/adaptor/reversed.hpp>
#include <libdevcore/Common.h>
#include <libdevcrypto/SHA3.h>
#include <libsolidity/AST.h>
@@ -823,26 +824,58 @@ unsigned ExpressionCompiler::appendArgumentCopyToMemory(TypePointers const& _typ
return length;
}
-unsigned ExpressionCompiler::appendExpressionCopyToMemory(Type const& _expectedType,
- Expression const& _expression, unsigned _memoryOffset)
+unsigned ExpressionCompiler::appendTypeConversionAndMoveToMemory(Type const& _expectedType, Type const& _type,
+ Location const& _location, unsigned _memoryOffset)
{
- _expression.accept(*this);
- appendTypeConversion(*_expression.getType(), _expectedType, true);
+ appendTypeConversion(_type, _expectedType, true);
unsigned const c_numBytes = CompilerUtils::getPaddedSize(_expectedType.getCalldataEncodedSize());
if (c_numBytes == 0 || c_numBytes > 32)
BOOST_THROW_EXCEPTION(CompilerError()
- << errinfo_sourceLocation(_expression.getLocation())
+ << errinfo_sourceLocation(_location)
<< errinfo_comment("Type " + _expectedType.toString() + " not yet supported."));
bool const c_leftAligned = _expectedType.getCategory() == Type::Category::STRING;
bool const c_padToWords = true;
return CompilerUtils(m_context).storeInMemory(_memoryOffset, c_numBytes, c_leftAligned, c_padToWords);
}
+unsigned ExpressionCompiler::appendExpressionCopyToMemory(Type const& _expectedType,
+ Expression const& _expression,
+ unsigned _memoryOffset)
+{
+ _expression.accept(*this);
+ return appendTypeConversionAndMoveToMemory(_expectedType, *_expression.getType(), _expression.getLocation(), _memoryOffset);
+}
+
void ExpressionCompiler::appendStateVariableAccessor(VariableDeclaration const& _varDecl)
{
- m_currentLValue.fromStateVariable(_varDecl, _varDecl.getType());
- solAssert(m_currentLValue.isInStorage(), "");
- m_currentLValue.retrieveValue(_varDecl.getType(), Location(), true);
+ FunctionType thisType(_varDecl);
+ solAssert(thisType.getReturnParameterTypes().size() == 1, "");
+ TypePointer const& resultType = thisType.getReturnParameterTypes().front();
+ unsigned sizeOnStack;
+
+ unsigned length = 0;
+ TypePointers const& params = thisType.getParameterTypes();
+ // move arguments to memory
+ for (TypePointer const& param: boost::adaptors::reverse(params))
+ length += appendTypeConversionAndMoveToMemory(*param, *param, Location(), length);
+
+ // retrieve the position of the mapping
+ m_context << m_context.getStorageLocationOfVariable(_varDecl);
+
+ for (TypePointer const& param: params)
+ {
+ // move offset to memory
+ CompilerUtils(m_context).storeInMemory(length);
+ unsigned argLen = CompilerUtils::getPaddedSize(param->getCalldataEncodedSize());
+ length -= argLen;
+ m_context << u256(argLen + 32) << u256(length) << eth::Instruction::SHA3;
+ }
+
+ m_currentLValue = LValue(m_context, LValue::STORAGE, *resultType);
+ m_currentLValue.retrieveValue(resultType, Location(), true);
+ sizeOnStack = resultType->getSizeOnStack();
+ solAssert(sizeOnStack <= 15, "Stack too deep.");
+ m_context << eth::dupInstruction(sizeOnStack + 1) << eth::Instruction::JUMP;
}
ExpressionCompiler::LValue::LValue(CompilerContext& _compilerContext, LValueType _type, Type const& _dataType,
diff --git a/ExpressionCompiler.h b/ExpressionCompiler.h
index caecbfe8..7de577e6 100644
--- a/ExpressionCompiler.h
+++ b/ExpressionCompiler.h
@@ -97,6 +97,10 @@ private:
unsigned appendArgumentCopyToMemory(TypePointers const& _types,
std::vector<ASTPointer<Expression const>> const& _arguments,
unsigned _memoryOffset = 0);
+ /// Appends code that copies a type to memory.
+ /// @returns the number of bytes copied to memory
+ unsigned appendTypeConversionAndMoveToMemory(Type const& _expectedType, Type const& _type,
+ Location const& _location, unsigned _memoryOffset = 0);
/// Appends code that evaluates a single expression and copies it to memory (with optional offset).
/// @returns the number of bytes copied to memory
unsigned appendExpressionCopyToMemory(Type const& _expectedType, Expression const& _expression,
diff --git a/Types.cpp b/Types.cpp
index ab401332..cfb852c2 100644
--- a/Types.cpp
+++ b/Types.cpp
@@ -621,11 +621,24 @@ FunctionType::FunctionType(FunctionDefinition const& _function, bool _isInternal
FunctionType::FunctionType(VariableDeclaration const& _varDecl):
m_location(Location::EXTERNAL), m_isConstant(true), m_declaration(&_varDecl)
{
- TypePointers params({});
- vector<string> paramNames({});
- TypePointers retParams({_varDecl.getType()});
- vector<string> retParamNames({ _varDecl.getName()});
- // for now, no input parameters LTODO: change for some things like mapping
+ TypePointers params;
+ vector<string> paramNames;
+ TypePointers retParams;
+ vector<string> retParamNames;
+ TypePointer varDeclType = _varDecl.getType();
+ auto mappingType = dynamic_cast<MappingType const*>(varDeclType.get());
+ auto returnType = varDeclType;
+
+ while (mappingType!= nullptr)
+ {
+ params.push_back(mappingType->getKeyType());
+ paramNames.push_back("");
+ returnType = mappingType->getValueType();
+ mappingType = dynamic_cast<MappingType const*>(mappingType->getValueType().get());
+ }
+
+ retParams.push_back(returnType);
+ retParamNames.push_back("");
swap(params, m_parameterTypes);
swap(paramNames, m_parameterNames);