diff options
author | chriseth <c@ethdev.com> | 2015-06-17 18:01:39 +0800 |
---|---|---|
committer | chriseth <c@ethdev.com> | 2015-06-17 20:25:00 +0800 |
commit | 1ff8dbebab1aa450e6800fd188e21aa7944b898c (patch) | |
tree | 0b1c58115344a07fd4bced57c66c2907258ac21b /ExpressionCompiler.cpp | |
parent | 17efc422996979289a9c5aa02959066578b09aa8 (diff) | |
download | dexon-solidity-1ff8dbebab1aa450e6800fd188e21aa7944b898c.tar dexon-solidity-1ff8dbebab1aa450e6800fd188e21aa7944b898c.tar.gz dexon-solidity-1ff8dbebab1aa450e6800fd188e21aa7944b898c.tar.bz2 dexon-solidity-1ff8dbebab1aa450e6800fd188e21aa7944b898c.tar.lz dexon-solidity-1ff8dbebab1aa450e6800fd188e21aa7944b898c.tar.xz dexon-solidity-1ff8dbebab1aa450e6800fd188e21aa7944b898c.tar.zst dexon-solidity-1ff8dbebab1aa450e6800fd188e21aa7944b898c.zip |
Accessors for strings.
Diffstat (limited to 'ExpressionCompiler.cpp')
-rw-r--r-- | ExpressionCompiler.cpp | 34 |
1 files changed, 20 insertions, 14 deletions
diff --git a/ExpressionCompiler.cpp b/ExpressionCompiler.cpp index c98d76f3..bfb945d8 100644 --- a/ExpressionCompiler.cpp +++ b/ExpressionCompiler.cpp @@ -109,34 +109,40 @@ void ExpressionCompiler::appendStateVariableAccessor(VariableDeclaration const& } unsigned retSizeOnStack = 0; solAssert(accessorType.getReturnParameterTypes().size() >= 1, ""); + auto const& returnTypes = accessorType.getReturnParameterTypes(); if (StructType const* structType = dynamic_cast<StructType const*>(returnType.get())) { // remove offset m_context << eth::Instruction::POP; auto const& names = accessorType.getReturnParameterNames(); - auto const& types = accessorType.getReturnParameterTypes(); // struct for (size_t i = 0; i < names.size(); ++i) { - if (types[i]->getCategory() == Type::Category::Mapping || types[i]->getCategory() == Type::Category::Array) + if (returnTypes[i]->getCategory() == Type::Category::Mapping) continue; + if (auto arrayType = dynamic_cast<ArrayType const*>(returnTypes[i].get())) + if (!arrayType->isByteArray()) + continue; pair<u256, unsigned> const& offsets = structType->getStorageOffsetsOfMember(names[i]); m_context << eth::Instruction::DUP1 << u256(offsets.first) << eth::Instruction::ADD << u256(offsets.second); - StorageItem(m_context, *types[i]).retrieveValue(SourceLocation(), true); - solAssert(types[i]->getSizeOnStack() == 1, "Returning struct elements with stack size != 1 is not yet implemented."); - m_context << eth::Instruction::SWAP1; - retSizeOnStack += types[i]->getSizeOnStack(); + TypePointer memberType = structType->getMemberType(names[i]); + StorageItem(m_context, *memberType).retrieveValue(SourceLocation(), true); + utils().convertType(*memberType, *returnTypes[i]); + utils().moveToStackTop(returnTypes[i]->getSizeOnStack()); + retSizeOnStack += returnTypes[i]->getSizeOnStack(); } // remove slot m_context << eth::Instruction::POP; } else { - // simple value - solAssert(accessorType.getReturnParameterTypes().size() == 1, ""); + // simple value or array + solAssert(returnTypes.size() == 1, ""); StorageItem(m_context, *returnType).retrieveValue(SourceLocation(), true); - retSizeOnStack = returnType->getSizeOnStack(); + utils().convertType(*returnType, *returnTypes.front()); + retSizeOnStack = returnTypes.front()->getSizeOnStack(); } + solAssert(retSizeOnStack == utils().getSizeOnStack(returnTypes), ""); solAssert(retSizeOnStack <= 15, "Stack is too deep."); m_context << eth::dupInstruction(retSizeOnStack + 1); m_context.appendJump(eth::AssemblyItem::JumpType::OutOfFunction); @@ -147,7 +153,7 @@ bool ExpressionCompiler::visit(Assignment const& _assignment) CompilerContext::LocationSetter locationSetter(m_context, _assignment); _assignment.getRightHandSide().accept(*this); TypePointer type = _assignment.getRightHandSide().getType(); - if (!_assignment.getType()->isInStorage()) + if (!_assignment.getType()->dataStoredIn(DataLocation::Storage)) { utils().convertType(*type, *_assignment.getType()); type = _assignment.getType(); @@ -712,10 +718,10 @@ void ExpressionCompiler::endVisit(MemberAccess const& _memberAccess) else switch (type.location()) { - case ReferenceType::Location::CallData: + case DataLocation::CallData: m_context << eth::Instruction::SWAP1 << eth::Instruction::POP; break; - case ReferenceType::Location::Storage: + case DataLocation::Storage: setLValue<StorageArrayLength>(_memberAccess, type); break; default: @@ -758,13 +764,13 @@ bool ExpressionCompiler::visit(IndexAccess const& _indexAccess) solAssert(_indexAccess.getIndexExpression(), "Index expression expected."); // remove storage byte offset - if (arrayType.location() == ReferenceType::Location::Storage) + if (arrayType.location() == DataLocation::Storage) m_context << eth::Instruction::POP; _indexAccess.getIndexExpression()->accept(*this); // stack layout: <base_ref> [<length>] <index> ArrayUtils(m_context).accessIndex(arrayType); - if (arrayType.location() == ReferenceType::Location::Storage) + if (arrayType.location() == DataLocation::Storage) { if (arrayType.isByteArray()) { |