aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorchriseth <c@ethdev.com>2015-08-04 00:09:39 +0800
committerchriseth <c@ethdev.com>2015-08-04 00:10:08 +0800
commit6daa27622a06ec7b8a4d67e4d8a1e2dcaa1be982 (patch)
tree83361eb2e9d2c3084bc8e4d84c181e14010524c2
parent2c476390cadea8a4863b0d29958d53b2a194fcb2 (diff)
downloaddexon-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.cpp3
-rw-r--r--ExpressionCompiler.cpp35
-rw-r--r--Types.cpp2
3 files changed, 30 insertions, 10 deletions
diff --git a/AST.cpp b/AST.cpp
index ee6e5225..05e2d52e 100644
--- a/AST.cpp
+++ b/AST.cpp
@@ -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);
}
diff --git a/Types.cpp b/Types.cpp
index d85c0511..89ff2134 100644
--- a/Types.cpp
+++ b/Types.cpp
@@ -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);
}