mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
strings as mapping keys.
This commit is contained in:
parent
2c476390ca
commit
6daa27622a
3
AST.cpp
3
AST.cpp
@ -784,8 +784,7 @@ void Expression::expectType(Type const& _expectedType)
|
|||||||
" is not implicitly convertible to expected type " +
|
" is not implicitly convertible to expected type " +
|
||||||
_expectedType.toString() +
|
_expectedType.toString() +
|
||||||
"."
|
"."
|
||||||
)
|
));
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Expression::requireLValue()
|
void Expression::requireLValue()
|
||||||
|
@ -85,6 +85,10 @@ void ExpressionCompiler::appendStateVariableAccessor(VariableDeclaration const&
|
|||||||
if (auto mappingType = dynamic_cast<MappingType const*>(returnType.get()))
|
if (auto mappingType = dynamic_cast<MappingType const*>(returnType.get()))
|
||||||
{
|
{
|
||||||
solAssert(CompilerUtils::freeMemoryPointer >= 0x40, "");
|
solAssert(CompilerUtils::freeMemoryPointer >= 0x40, "");
|
||||||
|
solAssert(
|
||||||
|
!paramTypes[i]->isDynamicallySized(),
|
||||||
|
"Accessors for mapping with dynamically-sized keys not yet implemented."
|
||||||
|
);
|
||||||
// pop offset
|
// pop offset
|
||||||
m_context << eth::Instruction::POP;
|
m_context << eth::Instruction::POP;
|
||||||
// move storage offset to memory.
|
// move storage offset to memory.
|
||||||
@ -803,15 +807,30 @@ bool ExpressionCompiler::visit(IndexAccess const& _indexAccess)
|
|||||||
if (baseType.getCategory() == Type::Category::Mapping)
|
if (baseType.getCategory() == Type::Category::Mapping)
|
||||||
{
|
{
|
||||||
// stack: storage_base_ref
|
// stack: storage_base_ref
|
||||||
Type const& keyType = *dynamic_cast<MappingType const&>(baseType).getKeyType();
|
auto const& mapping = dynamic_cast<MappingType const&>(baseType);
|
||||||
m_context << u256(0); // memory position
|
Type const& keyType = *mapping.getKeyType();
|
||||||
solAssert(_indexAccess.getIndexExpression(), "Index expression expected.");
|
solAssert(_indexAccess.getIndexExpression(), "Index expression expected.");
|
||||||
solAssert(keyType.getCalldataEncodedSize() <= 0x20, "Dynamic keys not yet implemented.");
|
if (keyType.isDynamicallySized())
|
||||||
appendExpressionCopyToMemory(keyType, *_indexAccess.getIndexExpression());
|
{
|
||||||
m_context << eth::Instruction::SWAP1;
|
_indexAccess.getIndexExpression()->accept(*this);
|
||||||
solAssert(CompilerUtils::freeMemoryPointer >= 0x40, "");
|
utils().fetchFreeMemoryPointer();
|
||||||
utils().storeInMemoryDynamic(IntegerType(256));
|
// stack: base index mem
|
||||||
m_context << u256(0) << eth::Instruction::SHA3;
|
// 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);
|
m_context << u256(0);
|
||||||
setLValueToStorageItem(_indexAccess);
|
setLValueToStorageItem(_indexAccess);
|
||||||
}
|
}
|
||||||
|
@ -179,6 +179,8 @@ TypePointer Type::fromMapping(ElementaryTypeName& _keyType, TypeName& _valueType
|
|||||||
BOOST_THROW_EXCEPTION(_valueType.createTypeError("Invalid type name."));
|
BOOST_THROW_EXCEPTION(_valueType.createTypeError("Invalid type name."));
|
||||||
// Convert value type to storage reference.
|
// Convert value type to storage reference.
|
||||||
valueType = ReferenceType::copyForLocationIfReference(DataLocation::Storage, valueType);
|
valueType = ReferenceType::copyForLocationIfReference(DataLocation::Storage, valueType);
|
||||||
|
// Convert key type to memory.
|
||||||
|
keyType = ReferenceType::copyForLocationIfReference(DataLocation::Memory, keyType);
|
||||||
return make_shared<MappingType>(keyType, valueType);
|
return make_shared<MappingType>(keyType, valueType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user