aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristian <c@ethdev.com>2015-02-07 02:57:08 +0800
committerChristian <c@ethdev.com>2015-02-07 03:04:02 +0800
commit724ee769005095a123704962cd56b97765278871 (patch)
tree0f4ac0b8778823e9ed4c53e75ecd60871f0a669b
parent82edc1ca6d694ad022c6b0e251da70393dfeb38a (diff)
downloaddexon-solidity-724ee769005095a123704962cd56b97765278871.tar
dexon-solidity-724ee769005095a123704962cd56b97765278871.tar.gz
dexon-solidity-724ee769005095a123704962cd56b97765278871.tar.bz2
dexon-solidity-724ee769005095a123704962cd56b97765278871.tar.lz
dexon-solidity-724ee769005095a123704962cd56b97765278871.tar.xz
dexon-solidity-724ee769005095a123704962cd56b97765278871.tar.zst
dexon-solidity-724ee769005095a123704962cd56b97765278871.zip
Accessors for structs.
-rw-r--r--ExpressionCompiler.cpp47
-rw-r--r--Types.cpp27
2 files changed, 54 insertions, 20 deletions
diff --git a/ExpressionCompiler.cpp b/ExpressionCompiler.cpp
index 875e00bc..f0c3af22 100644
--- a/ExpressionCompiler.cpp
+++ b/ExpressionCompiler.cpp
@@ -867,19 +867,17 @@ unsigned ExpressionCompiler::appendExpressionCopyToMemory(Type const& _expectedT
void ExpressionCompiler::appendStateVariableAccessor(VariableDeclaration const& _varDecl)
{
- FunctionType thisType(_varDecl);
- solAssert(thisType.getReturnParameterTypes().size() == 1, "");
- TypePointer const& resultType = thisType.getReturnParameterTypes().front();
- unsigned sizeOnStack;
+ FunctionType accessorType(_varDecl);
unsigned length = 0;
- TypePointers const& params = thisType.getParameterTypes();
+ TypePointers const& params = accessorType.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
+ // retrieve the position of the variable
m_context << m_context.getStorageLocationOfVariable(_varDecl);
+ TypePointer returnType = _varDecl.getType();
for (TypePointer const& param: params)
{
@@ -888,13 +886,40 @@ void ExpressionCompiler::appendStateVariableAccessor(VariableDeclaration const&
unsigned argLen = CompilerUtils::getPaddedSize(param->getCalldataEncodedSize());
length -= argLen;
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);
- m_currentLValue.retrieveValue(resultType, Location(), true);
- sizeOnStack = resultType->getSizeOnStack();
- solAssert(sizeOnStack <= 15, "Stack too deep.");
- m_context << eth::dupInstruction(sizeOnStack + 1) << eth::Instruction::JUMP;
+ unsigned retSizeOnStack = 0;
+ solAssert(accessorType.getReturnParameterTypes().size() >= 1, "");
+ if (StructType const* structType = dynamic_cast<StructType const*>(returnType.get()))
+ {
+ 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,
diff --git a/Types.cpp b/Types.cpp
index 38549594..e6f1e8e1 100644
--- a/Types.cpp
+++ b/Types.cpp
@@ -643,22 +643,31 @@ FunctionType::FunctionType(VariableDeclaration const& _varDecl):
{
TypePointers params;
vector<string> paramNames;
- TypePointers retParams;
- vector<string> retParamNames;
- TypePointer varDeclType = _varDecl.getType();
- auto mappingType = dynamic_cast<MappingType const*>(varDeclType.get());
- auto returnType = varDeclType;
+ auto returnType = _varDecl.getType();
- while (mappingType != nullptr)
+ while (auto mappingType = dynamic_cast<MappingType const*>(returnType.get()))
{
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("");
+ TypePointers retParams;
+ 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(paramNames, m_parameterNames);