diff options
| author | chriseth <c@ethdev.com> | 2015-08-04 00:09:39 +0800 |
|---|---|---|
| committer | chriseth <c@ethdev.com> | 2015-08-04 00:10:08 +0800 |
| commit | 6daa27622a06ec7b8a4d67e4d8a1e2dcaa1be982 (patch) | |
| tree | 83361eb2e9d2c3084bc8e4d84c181e14010524c2 | |
| parent | 2c476390cadea8a4863b0d29958d53b2a194fcb2 (diff) | |
| download | dexon-solidity-6daa27622a06ec7b8a4d67e4d8a1e2dcaa1be982.tar dexon-solidity-6daa27622a06ec7b8a4d67e4d8a1e2dcaa1be982.tar.gz dexon-solidity-6daa27622a06ec7b8a4d67e4d8a1e2dcaa1be982.tar.bz2 dexon-solidity-6daa27622a06ec7b8a4d67e4d8a1e2dcaa1be982.tar.lz dexon-solidity-6daa27622a06ec7b8a4d67e4d8a1e2dcaa1be982.tar.xz dexon-solidity-6daa27622a06ec7b8a4d67e4d8a1e2dcaa1be982.tar.zst dexon-solidity-6daa27622a06ec7b8a4d67e4d8a1e2dcaa1be982.zip | |
strings as mapping keys.
| -rw-r--r-- | AST.cpp | 3 | ||||
| -rw-r--r-- | ExpressionCompiler.cpp | 35 | ||||
| -rw-r--r-- | Types.cpp | 2 |
3 files changed, 30 insertions, 10 deletions
@@ -784,8 +784,7 @@ void Expression::expectType(Type const& _expectedType) " is not implicitly convertible to expected type " + _expectedType.toString() + "." - ) - ); + )); } void Expression::requireLValue() diff --git a/ExpressionCompiler.cpp b/ExpressionCompiler.cpp index 786d386d..f27cf5fe 100644 --- a/ExpressionCompiler.cpp +++ b/ExpressionCompiler.cpp @@ -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); } @@ -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); } |
