aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--CompilerUtils.cpp8
-rw-r--r--CompilerUtils.h2
-rw-r--r--ExpressionCompiler.cpp48
-rw-r--r--Types.cpp25
4 files changed, 45 insertions, 38 deletions
diff --git a/CompilerUtils.cpp b/CompilerUtils.cpp
index 511254fa..45495114 100644
--- a/CompilerUtils.cpp
+++ b/CompilerUtils.cpp
@@ -157,8 +157,12 @@ void CompilerUtils::copyToStackTop(unsigned _stackDepth, unsigned _itemSize)
void CompilerUtils::popStackElement(Type const& _type)
{
- unsigned const size = _type.getSizeOnStack();
- for (unsigned i = 0; i < size; ++i)
+ popStackSlots(_type.getSizeOnStack());
+}
+
+void CompilerUtils::popStackSlots(size_t _amount)
+{
+ for (size_t i = 0; i < _amount; ++i)
m_context << eth::Instruction::POP;
}
diff --git a/CompilerUtils.h b/CompilerUtils.h
index 043de41d..5b809bea 100644
--- a/CompilerUtils.h
+++ b/CompilerUtils.h
@@ -79,6 +79,8 @@ public:
void copyToStackTop(unsigned _stackDepth, unsigned _itemSize);
/// Removes the current value from the top of the stack.
void popStackElement(Type const& _type);
+ /// Removes element from the top of the stack _amount times.
+ void popStackSlots(size_t _amount);
template <class T>
static unsigned getSizeOnStack(std::vector<T> const& _variables);
diff --git a/ExpressionCompiler.cpp b/ExpressionCompiler.cpp
index 30cc3c6f..92fca636 100644
--- a/ExpressionCompiler.cpp
+++ b/ExpressionCompiler.cpp
@@ -60,43 +60,37 @@ void ExpressionCompiler::appendStateVariableAccessor(VariableDeclaration const&
CompilerContext::LocationSetter locationSetter(m_context, _varDecl);
FunctionType accessorType(_varDecl);
- unsigned length = 0;
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
auto const& location = m_context.getStorageLocationOfVariable(_varDecl);
m_context << location.first;
TypePointer returnType = _varDecl.getType();
- for (TypePointer const& paramType: mappingKeys)
- {
- // move offset to memory
- CompilerUtils(m_context).storeInMemory(length);
- unsigned argLen = paramType->getCalldataEncodedSize();
- length -= argLen;
- m_context << u256(argLen + 32) << u256(length) << eth::Instruction::SHA3;
-
- returnType = dynamic_cast<MappingType const&>(*returnType).getValueType();
- }
- if (finalMappingValueType->isDynamicallySized())
+ for (size_t i = 0; i < paramTypes.size(); ++i)
{
-
+ if (auto mappingType = dynamic_cast<MappingType const*>(returnType.get()))
+ {
+ // move storage offset to memory.
+ CompilerUtils(m_context).storeInMemory(32);
+ //move key to memory.
+ CompilerUtils(m_context).copyToStackTop(paramTypes.size() - i, 1);
+ CompilerUtils(m_context).storeInMemory(0);
+ m_context << u256(64) << u256(0) << eth::Instruction::SHA3;
+ 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;
solAssert(accessorType.getReturnParameterTypes().size() >= 1, "");
diff --git a/Types.cpp b/Types.cpp
index 9a5b120b..9ac909da 100644
--- a/Types.cpp
+++ b/Types.cpp
@@ -985,11 +985,23 @@ FunctionType::FunctionType(VariableDeclaration const& _varDecl):
vector<string> paramNames;
auto returnType = _varDecl.getType();
- while (auto mappingType = dynamic_cast<MappingType const*>(returnType.get()))
+ while (true)
{
- params.push_back(mappingType->getKeyType());
- paramNames.push_back("");
- returnType = mappingType->getValueType();
+ auto mappingType = dynamic_cast<MappingType const*>(returnType.get());
+ auto arrayType = dynamic_cast<ArrayType const*>(returnType.get());
+ 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;
@@ -1002,11 +1014,6 @@ FunctionType::FunctionType(VariableDeclaration const& _varDecl):
retParamNames.push_back(member.first);
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
{