aboutsummaryrefslogtreecommitdiffstats
path: root/ExpressionCompiler.cpp
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 /ExpressionCompiler.cpp
parent82edc1ca6d694ad022c6b0e251da70393dfeb38a (diff)
downloaddexon-solidity-724ee769005095a123704962cd56b97765278871.tar.gz
dexon-solidity-724ee769005095a123704962cd56b97765278871.tar.zst
dexon-solidity-724ee769005095a123704962cd56b97765278871.zip
Accessors for structs.
Diffstat (limited to 'ExpressionCompiler.cpp')
-rw-r--r--ExpressionCompiler.cpp47
1 files changed, 36 insertions, 11 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,