diff options
author | Gav Wood <g@ethdev.com> | 2015-02-04 00:47:46 +0800 |
---|---|---|
committer | Gav Wood <g@ethdev.com> | 2015-02-04 00:47:46 +0800 |
commit | 61c701b9ff6e7fdca0ffe91937d2e6a4cd20f7c4 (patch) | |
tree | fc7a3e83d2b6d313643402699c37925393d65156 | |
parent | adce36ff583389819638218e2a11c0887b35282c (diff) | |
parent | 8cd3d4b4b7a440815229288d853b6ed81ba4eb43 (diff) | |
download | dexon-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.cpp | 4 | ||||
-rw-r--r-- | ExpressionCompiler.cpp | 49 | ||||
-rw-r--r-- | ExpressionCompiler.h | 4 | ||||
-rw-r--r-- | Types.cpp | 23 |
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, @@ -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); |