mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
fixes
added more tests
This commit is contained in:
parent
fb1cf35f3b
commit
6f38bfeb6c
@ -64,7 +64,7 @@ void ExpressionCompiler::appendStateVariableAccessor(VariableDeclaration const&
|
|||||||
|
|
||||||
// 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 << u256(location.second);
|
||||||
|
|
||||||
TypePointer returnType = _varDecl.getType();
|
TypePointer returnType = _varDecl.getType();
|
||||||
|
|
||||||
@ -72,16 +72,22 @@ void ExpressionCompiler::appendStateVariableAccessor(VariableDeclaration const&
|
|||||||
{
|
{
|
||||||
if (auto mappingType = dynamic_cast<MappingType const*>(returnType.get()))
|
if (auto mappingType = dynamic_cast<MappingType const*>(returnType.get()))
|
||||||
{
|
{
|
||||||
|
// pop offset
|
||||||
|
m_context << eth::Instruction::POP;
|
||||||
// move storage offset to memory.
|
// move storage offset to memory.
|
||||||
CompilerUtils(m_context).storeInMemory(32);
|
CompilerUtils(m_context).storeInMemory(32);
|
||||||
//move key to memory.
|
// move key to memory.
|
||||||
CompilerUtils(m_context).copyToStackTop(paramTypes.size() - i, 1);
|
CompilerUtils(m_context).copyToStackTop(paramTypes.size() - i, 1);
|
||||||
CompilerUtils(m_context).storeInMemory(0);
|
CompilerUtils(m_context).storeInMemory(0);
|
||||||
m_context << u256(64) << u256(0) << eth::Instruction::SHA3;
|
m_context << u256(64) << u256(0) << eth::Instruction::SHA3;
|
||||||
|
// push offset
|
||||||
|
m_context << u256(0);
|
||||||
returnType = mappingType->getValueType();
|
returnType = mappingType->getValueType();
|
||||||
}
|
}
|
||||||
else if (auto arrayType = dynamic_cast<ArrayType const*>(returnType.get()))
|
else if (auto arrayType = dynamic_cast<ArrayType const*>(returnType.get()))
|
||||||
{
|
{
|
||||||
|
// pop offset
|
||||||
|
m_context << eth::Instruction::POP;
|
||||||
CompilerUtils(m_context).copyToStackTop(paramTypes.size() - i + 1, 1);
|
CompilerUtils(m_context).copyToStackTop(paramTypes.size() - i + 1, 1);
|
||||||
ArrayUtils(m_context).accessIndex(*arrayType);
|
ArrayUtils(m_context).accessIndex(*arrayType);
|
||||||
returnType = arrayType->getBaseType();
|
returnType = arrayType->getBaseType();
|
||||||
@ -89,19 +95,28 @@ void ExpressionCompiler::appendStateVariableAccessor(VariableDeclaration const&
|
|||||||
else
|
else
|
||||||
solAssert(false, "Index access is allowed only for \"mapping\" and \"array\" types.");
|
solAssert(false, "Index access is allowed only for \"mapping\" and \"array\" types.");
|
||||||
}
|
}
|
||||||
//remove index arguments.
|
// remove index arguments.
|
||||||
CompilerUtils(m_context).popStackSlots(paramTypes.size());
|
if (paramTypes.size() == 1)
|
||||||
|
m_context << eth::Instruction::SWAP2 << eth::Instruction::POP << eth::Instruction::SWAP1;
|
||||||
|
else if (paramTypes.size() >= 2)
|
||||||
|
{
|
||||||
|
m_context << eth::swapInstruction(paramTypes.size());
|
||||||
|
m_context << eth::Instruction::POP;
|
||||||
|
m_context << eth::swapInstruction(paramTypes.size());
|
||||||
|
CompilerUtils(m_context).popStackSlots(paramTypes.size() - 1);
|
||||||
|
}
|
||||||
unsigned retSizeOnStack = 0;
|
unsigned retSizeOnStack = 0;
|
||||||
solAssert(accessorType.getReturnParameterTypes().size() >= 1, "");
|
solAssert(accessorType.getReturnParameterTypes().size() >= 1, "");
|
||||||
if (StructType const* structType = dynamic_cast<StructType const*>(returnType.get()))
|
if (StructType const* structType = dynamic_cast<StructType const*>(returnType.get()))
|
||||||
{
|
{
|
||||||
|
// remove offset
|
||||||
|
m_context << eth::Instruction::POP;
|
||||||
auto const& names = accessorType.getReturnParameterNames();
|
auto const& names = accessorType.getReturnParameterNames();
|
||||||
auto const& types = accessorType.getReturnParameterTypes();
|
auto const& types = accessorType.getReturnParameterTypes();
|
||||||
// struct
|
// struct
|
||||||
for (size_t i = 0; i < names.size(); ++i)
|
for (size_t i = 0; i < names.size(); ++i)
|
||||||
{
|
{
|
||||||
if (types[i]->getCategory() == Type::Category::Mapping)
|
if (types[i]->getCategory() == Type::Category::Mapping || types[i]->getCategory() == Type::Category::Array)
|
||||||
continue;
|
continue;
|
||||||
pair<u256, unsigned> const& offsets = structType->getStorageOffsetsOfMember(names[i]);
|
pair<u256, unsigned> const& offsets = structType->getStorageOffsetsOfMember(names[i]);
|
||||||
m_context << eth::Instruction::DUP1 << u256(offsets.first) << eth::Instruction::ADD << u256(offsets.second);
|
m_context << eth::Instruction::DUP1 << u256(offsets.first) << eth::Instruction::ADD << u256(offsets.second);
|
||||||
@ -110,13 +125,13 @@ void ExpressionCompiler::appendStateVariableAccessor(VariableDeclaration const&
|
|||||||
m_context << eth::Instruction::SWAP1;
|
m_context << eth::Instruction::SWAP1;
|
||||||
retSizeOnStack += types[i]->getSizeOnStack();
|
retSizeOnStack += types[i]->getSizeOnStack();
|
||||||
}
|
}
|
||||||
|
// remove slot
|
||||||
m_context << eth::Instruction::POP;
|
m_context << eth::Instruction::POP;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// simple value
|
// simple value
|
||||||
solAssert(accessorType.getReturnParameterTypes().size() == 1, "");
|
solAssert(accessorType.getReturnParameterTypes().size() == 1, "");
|
||||||
m_context << u256(location.second);
|
|
||||||
StorageItem(m_context, *returnType).retrieveValue(SourceLocation(), true);
|
StorageItem(m_context, *returnType).retrieveValue(SourceLocation(), true);
|
||||||
retSizeOnStack = returnType->getSizeOnStack();
|
retSizeOnStack = returnType->getSizeOnStack();
|
||||||
}
|
}
|
||||||
|
17
Types.cpp
17
Types.cpp
@ -981,24 +981,23 @@ 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 paramTypes;
|
||||||
vector<string> paramNames;
|
vector<string> paramNames;
|
||||||
auto returnType = _varDecl.getType();
|
auto returnType = _varDecl.getType();
|
||||||
|
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
auto mappingType = dynamic_cast<MappingType const*>(returnType.get());
|
if (auto mappingType = dynamic_cast<MappingType const*>(returnType.get()))
|
||||||
auto arrayType = dynamic_cast<ArrayType const*>(returnType.get());
|
|
||||||
if (mappingType)
|
|
||||||
{
|
{
|
||||||
params.push_back(mappingType->getKeyType());
|
paramTypes.push_back(mappingType->getKeyType());
|
||||||
paramNames.push_back("");
|
paramNames.push_back("");
|
||||||
returnType = mappingType->getValueType();
|
returnType = mappingType->getValueType();
|
||||||
}
|
}
|
||||||
else if (arrayType)
|
else if (auto arrayType = dynamic_cast<ArrayType const*>(returnType.get()))
|
||||||
{
|
{
|
||||||
returnType = arrayType->getBaseType();
|
returnType = arrayType->getBaseType();
|
||||||
params.push_back(make_shared<IntegerType>(256));
|
paramNames.push_back("");
|
||||||
|
paramTypes.push_back(make_shared<IntegerType>(256));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
break;
|
break;
|
||||||
@ -1009,7 +1008,7 @@ FunctionType::FunctionType(VariableDeclaration const& _varDecl):
|
|||||||
if (auto structType = dynamic_cast<StructType const*>(returnType.get()))
|
if (auto structType = dynamic_cast<StructType const*>(returnType.get()))
|
||||||
{
|
{
|
||||||
for (pair<string, TypePointer> const& member: structType->getMembers())
|
for (pair<string, TypePointer> const& member: structType->getMembers())
|
||||||
if (member.second->canLiveOutsideStorage())
|
if (member.second->getCategory() != Category::Mapping && member.second->getCategory() != Category::Array)
|
||||||
{
|
{
|
||||||
retParamNames.push_back(member.first);
|
retParamNames.push_back(member.first);
|
||||||
retParams.push_back(member.second);
|
retParams.push_back(member.second);
|
||||||
@ -1021,7 +1020,7 @@ FunctionType::FunctionType(VariableDeclaration const& _varDecl):
|
|||||||
retParamNames.push_back("");
|
retParamNames.push_back("");
|
||||||
}
|
}
|
||||||
|
|
||||||
swap(params, m_parameterTypes);
|
swap(paramTypes, m_parameterTypes);
|
||||||
swap(paramNames, m_parameterNames);
|
swap(paramNames, m_parameterNames);
|
||||||
swap(retParams, m_returnParameterTypes);
|
swap(retParams, m_returnParameterTypes);
|
||||||
swap(retParamNames, m_returnParameterNames);
|
swap(retParamNames, m_returnParameterNames);
|
||||||
|
Loading…
Reference in New Issue
Block a user