mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
added implementation to append code for State variable accessor
fixed tests
This commit is contained in:
parent
df3ce3ad8f
commit
fb1cf35f3b
@ -157,8 +157,12 @@ void CompilerUtils::copyToStackTop(unsigned _stackDepth, unsigned _itemSize)
|
|||||||
|
|
||||||
void CompilerUtils::popStackElement(Type const& _type)
|
void CompilerUtils::popStackElement(Type const& _type)
|
||||||
{
|
{
|
||||||
unsigned const size = _type.getSizeOnStack();
|
popStackSlots(_type.getSizeOnStack());
|
||||||
for (unsigned i = 0; i < size; ++i)
|
}
|
||||||
|
|
||||||
|
void CompilerUtils::popStackSlots(size_t _amount)
|
||||||
|
{
|
||||||
|
for (size_t i = 0; i < _amount; ++i)
|
||||||
m_context << eth::Instruction::POP;
|
m_context << eth::Instruction::POP;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -79,6 +79,8 @@ public:
|
|||||||
void copyToStackTop(unsigned _stackDepth, unsigned _itemSize);
|
void copyToStackTop(unsigned _stackDepth, unsigned _itemSize);
|
||||||
/// Removes the current value from the top of the stack.
|
/// Removes the current value from the top of the stack.
|
||||||
void popStackElement(Type const& _type);
|
void popStackElement(Type const& _type);
|
||||||
|
/// Removes element from the top of the stack _amount times.
|
||||||
|
void popStackSlots(size_t _amount);
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
static unsigned getSizeOnStack(std::vector<T> const& _variables);
|
static unsigned getSizeOnStack(std::vector<T> const& _variables);
|
||||||
|
@ -60,43 +60,37 @@ void ExpressionCompiler::appendStateVariableAccessor(VariableDeclaration const&
|
|||||||
CompilerContext::LocationSetter locationSetter(m_context, _varDecl);
|
CompilerContext::LocationSetter locationSetter(m_context, _varDecl);
|
||||||
FunctionType accessorType(_varDecl);
|
FunctionType accessorType(_varDecl);
|
||||||
|
|
||||||
unsigned length = 0;
|
|
||||||
TypePointers const& paramTypes = accessorType.getParameterTypes();
|
TypePointers const& paramTypes = accessorType.getParameterTypes();
|
||||||
|
|
||||||
// to exclude the last key if it is an array
|
|
||||||
TypePointer finalMappingValueType = _varDecl.getType();
|
|
||||||
while (finalMappingValueType->getCategory() == Type::Category::Mapping)
|
|
||||||
finalMappingValueType = dynamic_cast<MappingType const&>(*finalMappingValueType).getValueType();
|
|
||||||
|
|
||||||
bool finalIsArrayType = finalMappingValueType->getCategory() == Type::Category::Array;
|
|
||||||
TypePointers mappingKeys(paramTypes);
|
|
||||||
if (finalIsArrayType)
|
|
||||||
mappingKeys.pop_back();
|
|
||||||
|
|
||||||
// move mapping arguments to memory
|
|
||||||
for (TypePointer const& paramType: boost::adaptors::reverse(mappingKeys))
|
|
||||||
length += CompilerUtils(m_context).storeInMemory(length, *paramType, true);
|
|
||||||
|
|
||||||
// retrieve the position of the variable
|
// retrieve the position of the variable
|
||||||
auto const& location = m_context.getStorageLocationOfVariable(_varDecl);
|
auto const& location = m_context.getStorageLocationOfVariable(_varDecl);
|
||||||
m_context << location.first;
|
m_context << location.first;
|
||||||
|
|
||||||
TypePointer returnType = _varDecl.getType();
|
TypePointer returnType = _varDecl.getType();
|
||||||
|
|
||||||
for (TypePointer const& paramType: mappingKeys)
|
for (size_t i = 0; i < paramTypes.size(); ++i)
|
||||||
{
|
{
|
||||||
// move offset to memory
|
if (auto mappingType = dynamic_cast<MappingType const*>(returnType.get()))
|
||||||
CompilerUtils(m_context).storeInMemory(length);
|
{
|
||||||
unsigned argLen = paramType->getCalldataEncodedSize();
|
// move storage offset to memory.
|
||||||
length -= argLen;
|
CompilerUtils(m_context).storeInMemory(32);
|
||||||
m_context << u256(argLen + 32) << u256(length) << eth::Instruction::SHA3;
|
//move key to memory.
|
||||||
|
CompilerUtils(m_context).copyToStackTop(paramTypes.size() - i, 1);
|
||||||
returnType = dynamic_cast<MappingType const&>(*returnType).getValueType();
|
CompilerUtils(m_context).storeInMemory(0);
|
||||||
}
|
m_context << u256(64) << u256(0) << eth::Instruction::SHA3;
|
||||||
if (finalMappingValueType->isDynamicallySized())
|
returnType = mappingType->getValueType();
|
||||||
{
|
}
|
||||||
|
else if (auto arrayType = dynamic_cast<ArrayType const*>(returnType.get()))
|
||||||
|
{
|
||||||
|
CompilerUtils(m_context).copyToStackTop(paramTypes.size() - i + 1, 1);
|
||||||
|
ArrayUtils(m_context).accessIndex(*arrayType);
|
||||||
|
returnType = arrayType->getBaseType();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
solAssert(false, "Index access is allowed only for \"mapping\" and \"array\" types.");
|
||||||
}
|
}
|
||||||
|
//remove index arguments.
|
||||||
|
CompilerUtils(m_context).popStackSlots(paramTypes.size());
|
||||||
|
|
||||||
unsigned retSizeOnStack = 0;
|
unsigned retSizeOnStack = 0;
|
||||||
solAssert(accessorType.getReturnParameterTypes().size() >= 1, "");
|
solAssert(accessorType.getReturnParameterTypes().size() >= 1, "");
|
||||||
|
25
Types.cpp
25
Types.cpp
@ -985,11 +985,23 @@ FunctionType::FunctionType(VariableDeclaration const& _varDecl):
|
|||||||
vector<string> paramNames;
|
vector<string> paramNames;
|
||||||
auto returnType = _varDecl.getType();
|
auto returnType = _varDecl.getType();
|
||||||
|
|
||||||
while (auto mappingType = dynamic_cast<MappingType const*>(returnType.get()))
|
while (true)
|
||||||
{
|
{
|
||||||
params.push_back(mappingType->getKeyType());
|
auto mappingType = dynamic_cast<MappingType const*>(returnType.get());
|
||||||
paramNames.push_back("");
|
auto arrayType = dynamic_cast<ArrayType const*>(returnType.get());
|
||||||
returnType = mappingType->getValueType();
|
if (mappingType)
|
||||||
|
{
|
||||||
|
params.push_back(mappingType->getKeyType());
|
||||||
|
paramNames.push_back("");
|
||||||
|
returnType = mappingType->getValueType();
|
||||||
|
}
|
||||||
|
else if (arrayType)
|
||||||
|
{
|
||||||
|
returnType = arrayType->getBaseType();
|
||||||
|
params.push_back(make_shared<IntegerType>(256));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
TypePointers retParams;
|
TypePointers retParams;
|
||||||
@ -1002,11 +1014,6 @@ FunctionType::FunctionType(VariableDeclaration const& _varDecl):
|
|||||||
retParamNames.push_back(member.first);
|
retParamNames.push_back(member.first);
|
||||||
retParams.push_back(member.second);
|
retParams.push_back(member.second);
|
||||||
}
|
}
|
||||||
} else if (auto arrayType = dynamic_cast<ArrayType const*>(returnType.get()))
|
|
||||||
{
|
|
||||||
params.push_back(make_shared<IntegerType>(256));
|
|
||||||
paramNames.push_back("");
|
|
||||||
returnType = arrayType->getBaseType();
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user