added more tests
This commit is contained in:
Liana Husikyan 2015-04-02 17:03:02 +02:00
parent fb1cf35f3b
commit 6f38bfeb6c
2 changed files with 30 additions and 16 deletions

View File

@ -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();
} }

View File

@ -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);