strings as mapping keys.

This commit is contained in:
chriseth 2015-08-03 18:09:39 +02:00
parent 2c476390ca
commit 6daa27622a
3 changed files with 30 additions and 10 deletions

View File

@ -784,8 +784,7 @@ void Expression::expectType(Type const& _expectedType)
" is not implicitly convertible to expected type " +
_expectedType.toString() +
"."
)
);
));
}
void Expression::requireLValue()

View File

@ -85,6 +85,10 @@ void ExpressionCompiler::appendStateVariableAccessor(VariableDeclaration const&
if (auto mappingType = dynamic_cast<MappingType const*>(returnType.get()))
{
solAssert(CompilerUtils::freeMemoryPointer >= 0x40, "");
solAssert(
!paramTypes[i]->isDynamicallySized(),
"Accessors for mapping with dynamically-sized keys not yet implemented."
);
// pop offset
m_context << eth::Instruction::POP;
// move storage offset to memory.
@ -803,15 +807,30 @@ bool ExpressionCompiler::visit(IndexAccess const& _indexAccess)
if (baseType.getCategory() == Type::Category::Mapping)
{
// stack: storage_base_ref
Type const& keyType = *dynamic_cast<MappingType const&>(baseType).getKeyType();
m_context << u256(0); // memory position
auto const& mapping = dynamic_cast<MappingType const&>(baseType);
Type const& keyType = *mapping.getKeyType();
solAssert(_indexAccess.getIndexExpression(), "Index expression expected.");
solAssert(keyType.getCalldataEncodedSize() <= 0x20, "Dynamic keys not yet implemented.");
appendExpressionCopyToMemory(keyType, *_indexAccess.getIndexExpression());
m_context << eth::Instruction::SWAP1;
solAssert(CompilerUtils::freeMemoryPointer >= 0x40, "");
utils().storeInMemoryDynamic(IntegerType(256));
m_context << u256(0) << eth::Instruction::SHA3;
if (keyType.isDynamicallySized())
{
_indexAccess.getIndexExpression()->accept(*this);
utils().fetchFreeMemoryPointer();
// stack: base index mem
// note: the following operations must not allocate memory!
utils().encodeToMemory(TypePointers{mapping.getKeyType()}, TypePointers(), false, true);
m_context << eth::Instruction::SWAP1;
utils().storeInMemoryDynamic(IntegerType(256));
utils().toSizeAfterFreeMemoryPointer();
}
else
{
m_context << u256(0); // memory position
appendExpressionCopyToMemory(keyType, *_indexAccess.getIndexExpression());
m_context << eth::Instruction::SWAP1;
solAssert(CompilerUtils::freeMemoryPointer >= 0x40, "");
utils().storeInMemoryDynamic(IntegerType(256));
m_context << u256(0);
}
m_context << eth::Instruction::SHA3;
m_context << u256(0);
setLValueToStorageItem(_indexAccess);
}

View File

@ -179,6 +179,8 @@ TypePointer Type::fromMapping(ElementaryTypeName& _keyType, TypeName& _valueType
BOOST_THROW_EXCEPTION(_valueType.createTypeError("Invalid type name."));
// Convert value type to storage reference.
valueType = ReferenceType::copyForLocationIfReference(DataLocation::Storage, valueType);
// Convert key type to memory.
keyType = ReferenceType::copyForLocationIfReference(DataLocation::Memory, keyType);
return make_shared<MappingType>(keyType, valueType);
}