mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Accessors for structs.
This commit is contained in:
parent
82edc1ca6d
commit
724ee76900
@ -867,19 +867,17 @@ unsigned ExpressionCompiler::appendExpressionCopyToMemory(Type const& _expectedT
|
|||||||
|
|
||||||
void ExpressionCompiler::appendStateVariableAccessor(VariableDeclaration const& _varDecl)
|
void ExpressionCompiler::appendStateVariableAccessor(VariableDeclaration const& _varDecl)
|
||||||
{
|
{
|
||||||
FunctionType thisType(_varDecl);
|
FunctionType accessorType(_varDecl);
|
||||||
solAssert(thisType.getReturnParameterTypes().size() == 1, "");
|
|
||||||
TypePointer const& resultType = thisType.getReturnParameterTypes().front();
|
|
||||||
unsigned sizeOnStack;
|
|
||||||
|
|
||||||
unsigned length = 0;
|
unsigned length = 0;
|
||||||
TypePointers const& params = thisType.getParameterTypes();
|
TypePointers const& params = accessorType.getParameterTypes();
|
||||||
// move arguments to memory
|
// move arguments to memory
|
||||||
for (TypePointer const& param: boost::adaptors::reverse(params))
|
for (TypePointer const& param: boost::adaptors::reverse(params))
|
||||||
length += appendTypeConversionAndMoveToMemory(*param, *param, Location(), length);
|
length += appendTypeConversionAndMoveToMemory(*param, *param, Location(), length);
|
||||||
|
|
||||||
// retrieve the position of the mapping
|
// retrieve the position of the variable
|
||||||
m_context << m_context.getStorageLocationOfVariable(_varDecl);
|
m_context << m_context.getStorageLocationOfVariable(_varDecl);
|
||||||
|
TypePointer returnType = _varDecl.getType();
|
||||||
|
|
||||||
for (TypePointer const& param: params)
|
for (TypePointer const& param: params)
|
||||||
{
|
{
|
||||||
@ -888,13 +886,40 @@ void ExpressionCompiler::appendStateVariableAccessor(VariableDeclaration const&
|
|||||||
unsigned argLen = CompilerUtils::getPaddedSize(param->getCalldataEncodedSize());
|
unsigned argLen = CompilerUtils::getPaddedSize(param->getCalldataEncodedSize());
|
||||||
length -= argLen;
|
length -= argLen;
|
||||||
m_context << u256(argLen + 32) << u256(length) << eth::Instruction::SHA3;
|
m_context << u256(argLen + 32) << u256(length) << eth::Instruction::SHA3;
|
||||||
|
|
||||||
|
returnType = dynamic_cast<MappingType const&>(*returnType).getValueType();
|
||||||
}
|
}
|
||||||
|
|
||||||
m_currentLValue = LValue(m_context, LValue::STORAGE, *resultType);
|
unsigned retSizeOnStack = 0;
|
||||||
m_currentLValue.retrieveValue(resultType, Location(), true);
|
solAssert(accessorType.getReturnParameterTypes().size() >= 1, "");
|
||||||
sizeOnStack = resultType->getSizeOnStack();
|
if (StructType const* structType = dynamic_cast<StructType const*>(returnType.get()))
|
||||||
solAssert(sizeOnStack <= 15, "Stack too deep.");
|
{
|
||||||
m_context << eth::dupInstruction(sizeOnStack + 1) << eth::Instruction::JUMP;
|
auto const& names = accessorType.getReturnParameterNames();
|
||||||
|
auto const& types = accessorType.getReturnParameterTypes();
|
||||||
|
// struct
|
||||||
|
for (size_t i = 0; i < names.size(); ++i)
|
||||||
|
{
|
||||||
|
m_context << eth::Instruction::DUP1
|
||||||
|
<< structType->getStorageOffsetOfMember(names[i])
|
||||||
|
<< eth::Instruction::ADD;
|
||||||
|
m_currentLValue = LValue(m_context, LValue::STORAGE, *types[i]);
|
||||||
|
m_currentLValue.retrieveValue(types[i], Location(), true);
|
||||||
|
solAssert(types[i]->getSizeOnStack() == 1, "Returning struct elements with stack size != 1 not yet implemented.");
|
||||||
|
m_context << eth::Instruction::SWAP1;
|
||||||
|
retSizeOnStack += types[i]->getSizeOnStack();
|
||||||
|
}
|
||||||
|
m_context << eth::Instruction::POP;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// simple value
|
||||||
|
solAssert(accessorType.getReturnParameterTypes().size() == 1, "");
|
||||||
|
m_currentLValue = LValue(m_context, LValue::STORAGE, *returnType);
|
||||||
|
m_currentLValue.retrieveValue(returnType, Location(), true);
|
||||||
|
retSizeOnStack = returnType->getSizeOnStack();
|
||||||
|
}
|
||||||
|
solAssert(retSizeOnStack <= 15, "Stack too deep.");
|
||||||
|
m_context << eth::dupInstruction(retSizeOnStack + 1) << eth::Instruction::JUMP;
|
||||||
}
|
}
|
||||||
|
|
||||||
ExpressionCompiler::LValue::LValue(CompilerContext& _compilerContext, LValueType _type, Type const& _dataType,
|
ExpressionCompiler::LValue::LValue(CompilerContext& _compilerContext, LValueType _type, Type const& _dataType,
|
||||||
|
27
Types.cpp
27
Types.cpp
@ -643,22 +643,31 @@ FunctionType::FunctionType(VariableDeclaration const& _varDecl):
|
|||||||
{
|
{
|
||||||
TypePointers params;
|
TypePointers params;
|
||||||
vector<string> paramNames;
|
vector<string> paramNames;
|
||||||
TypePointers retParams;
|
auto returnType = _varDecl.getType();
|
||||||
vector<string> retParamNames;
|
|
||||||
TypePointer varDeclType = _varDecl.getType();
|
|
||||||
auto mappingType = dynamic_cast<MappingType const*>(varDeclType.get());
|
|
||||||
auto returnType = varDeclType;
|
|
||||||
|
|
||||||
while (mappingType != nullptr)
|
while (auto mappingType = dynamic_cast<MappingType const*>(returnType.get()))
|
||||||
{
|
{
|
||||||
params.push_back(mappingType->getKeyType());
|
params.push_back(mappingType->getKeyType());
|
||||||
paramNames.push_back("");
|
paramNames.push_back("");
|
||||||
returnType = mappingType->getValueType();
|
returnType = mappingType->getValueType();
|
||||||
mappingType = dynamic_cast<MappingType const*>(mappingType->getValueType().get());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
retParams.push_back(returnType);
|
TypePointers retParams;
|
||||||
retParamNames.push_back("");
|
vector<string> retParamNames;
|
||||||
|
if (auto structType = dynamic_cast<StructType const*>(returnType.get()))
|
||||||
|
{
|
||||||
|
for (pair<string, TypePointer> const& member: structType->getMembers())
|
||||||
|
if (member.second->canLiveOutsideStorage())
|
||||||
|
{
|
||||||
|
retParamNames.push_back(member.first);
|
||||||
|
retParams.push_back(member.second);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
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