mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Merge pull request #922 from LefterisJP/sol_AccessorsMapping
Sol state variable accessors for mapping
This commit is contained in:
commit
61c701b9ff
@ -240,10 +240,6 @@ bool Compiler::visit(VariableDeclaration const& _variableDeclaration)
|
|||||||
m_context << m_context.getFunctionEntryLabel(_variableDeclaration);
|
m_context << m_context.getFunctionEntryLabel(_variableDeclaration);
|
||||||
ExpressionCompiler::appendStateVariableAccessor(m_context, _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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
|
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include <numeric>
|
#include <numeric>
|
||||||
|
#include <boost/range/adaptor/reversed.hpp>
|
||||||
#include <libdevcore/Common.h>
|
#include <libdevcore/Common.h>
|
||||||
#include <libdevcrypto/SHA3.h>
|
#include <libdevcrypto/SHA3.h>
|
||||||
#include <libsolidity/AST.h>
|
#include <libsolidity/AST.h>
|
||||||
@ -823,26 +824,58 @@ unsigned ExpressionCompiler::appendArgumentCopyToMemory(TypePointers const& _typ
|
|||||||
return length;
|
return length;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned ExpressionCompiler::appendExpressionCopyToMemory(Type const& _expectedType,
|
unsigned ExpressionCompiler::appendTypeConversionAndMoveToMemory(Type const& _expectedType, Type const& _type,
|
||||||
Expression const& _expression, unsigned _memoryOffset)
|
Location const& _location, unsigned _memoryOffset)
|
||||||
{
|
{
|
||||||
_expression.accept(*this);
|
appendTypeConversion(_type, _expectedType, true);
|
||||||
appendTypeConversion(*_expression.getType(), _expectedType, true);
|
|
||||||
unsigned const c_numBytes = CompilerUtils::getPaddedSize(_expectedType.getCalldataEncodedSize());
|
unsigned const c_numBytes = CompilerUtils::getPaddedSize(_expectedType.getCalldataEncodedSize());
|
||||||
if (c_numBytes == 0 || c_numBytes > 32)
|
if (c_numBytes == 0 || c_numBytes > 32)
|
||||||
BOOST_THROW_EXCEPTION(CompilerError()
|
BOOST_THROW_EXCEPTION(CompilerError()
|
||||||
<< errinfo_sourceLocation(_expression.getLocation())
|
<< errinfo_sourceLocation(_location)
|
||||||
<< errinfo_comment("Type " + _expectedType.toString() + " not yet supported."));
|
<< errinfo_comment("Type " + _expectedType.toString() + " not yet supported."));
|
||||||
bool const c_leftAligned = _expectedType.getCategory() == Type::Category::STRING;
|
bool const c_leftAligned = _expectedType.getCategory() == Type::Category::STRING;
|
||||||
bool const c_padToWords = true;
|
bool const c_padToWords = true;
|
||||||
return CompilerUtils(m_context).storeInMemory(_memoryOffset, c_numBytes, c_leftAligned, c_padToWords);
|
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)
|
void ExpressionCompiler::appendStateVariableAccessor(VariableDeclaration const& _varDecl)
|
||||||
{
|
{
|
||||||
m_currentLValue.fromStateVariable(_varDecl, _varDecl.getType());
|
FunctionType thisType(_varDecl);
|
||||||
solAssert(m_currentLValue.isInStorage(), "");
|
solAssert(thisType.getReturnParameterTypes().size() == 1, "");
|
||||||
m_currentLValue.retrieveValue(_varDecl.getType(), Location(), true);
|
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,
|
ExpressionCompiler::LValue::LValue(CompilerContext& _compilerContext, LValueType _type, Type const& _dataType,
|
||||||
|
@ -97,6 +97,10 @@ private:
|
|||||||
unsigned appendArgumentCopyToMemory(TypePointers const& _types,
|
unsigned appendArgumentCopyToMemory(TypePointers const& _types,
|
||||||
std::vector<ASTPointer<Expression const>> const& _arguments,
|
std::vector<ASTPointer<Expression const>> const& _arguments,
|
||||||
unsigned _memoryOffset = 0);
|
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).
|
/// Appends code that evaluates a single expression and copies it to memory (with optional offset).
|
||||||
/// @returns the number of bytes copied to memory
|
/// @returns the number of bytes copied to memory
|
||||||
unsigned appendExpressionCopyToMemory(Type const& _expectedType, Expression const& _expression,
|
unsigned appendExpressionCopyToMemory(Type const& _expectedType, Expression const& _expression,
|
||||||
|
23
Types.cpp
23
Types.cpp
@ -621,11 +621,24 @@ FunctionType::FunctionType(FunctionDefinition const& _function, bool _isInternal
|
|||||||
FunctionType::FunctionType(VariableDeclaration const& _varDecl):
|
FunctionType::FunctionType(VariableDeclaration const& _varDecl):
|
||||||
m_location(Location::EXTERNAL), m_isConstant(true), m_declaration(&_varDecl)
|
m_location(Location::EXTERNAL), m_isConstant(true), m_declaration(&_varDecl)
|
||||||
{
|
{
|
||||||
TypePointers params({});
|
TypePointers params;
|
||||||
vector<string> paramNames({});
|
vector<string> paramNames;
|
||||||
TypePointers retParams({_varDecl.getType()});
|
TypePointers retParams;
|
||||||
vector<string> retParamNames({ _varDecl.getName()});
|
vector<string> retParamNames;
|
||||||
// for now, no input parameters LTODO: change for some things like mapping
|
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(params, m_parameterTypes);
|
||||||
swap(paramNames, m_parameterNames);
|
swap(paramNames, m_parameterNames);
|
||||||
|
Loading…
Reference in New Issue
Block a user