aboutsummaryrefslogtreecommitdiffstats
path: root/ExpressionCompiler.cpp
diff options
context:
space:
mode:
authorchriseth <c@ethdev.com>2015-06-26 00:52:19 +0800
committerchriseth <c@ethdev.com>2015-06-26 00:52:19 +0800
commit2e5c52bfabdc7ac221bf4617ed98d9a9abef85b8 (patch)
treee2cf306d37298b8de3da3a9c0c29a024bfc3f080 /ExpressionCompiler.cpp
parentfb14a586f4084d8acb3a765f3995e2a5e7b3a5b3 (diff)
parent529ed468df4c8fc9947cf92b42a5da84c7434b49 (diff)
downloaddexon-solidity-2e5c52bfabdc7ac221bf4617ed98d9a9abef85b8.tar
dexon-solidity-2e5c52bfabdc7ac221bf4617ed98d9a9abef85b8.tar.gz
dexon-solidity-2e5c52bfabdc7ac221bf4617ed98d9a9abef85b8.tar.bz2
dexon-solidity-2e5c52bfabdc7ac221bf4617ed98d9a9abef85b8.tar.lz
dexon-solidity-2e5c52bfabdc7ac221bf4617ed98d9a9abef85b8.tar.xz
dexon-solidity-2e5c52bfabdc7ac221bf4617ed98d9a9abef85b8.tar.zst
dexon-solidity-2e5c52bfabdc7ac221bf4617ed98d9a9abef85b8.zip
Merge pull request #2276 from chriseth/sol_memoryArrays7
Copy routines for non-byte arrays.
Diffstat (limited to 'ExpressionCompiler.cpp')
-rw-r--r--ExpressionCompiler.cpp56
1 files changed, 56 insertions, 0 deletions
diff --git a/ExpressionCompiler.cpp b/ExpressionCompiler.cpp
index 7d6ed346..fb10eb83 100644
--- a/ExpressionCompiler.cpp
+++ b/ExpressionCompiler.cpp
@@ -56,6 +56,62 @@ void ExpressionCompiler::appendStateVariableInitialization(VariableDeclaration c
StorageItem(m_context, _varDecl).storeValue(*_varDecl.getType(), _varDecl.getLocation(), true);
}
+void ExpressionCompiler::appendStackVariableInitialisation(Type const& _type, bool _toMemory)
+{
+ CompilerUtils utils(m_context);
+ auto const* referenceType = dynamic_cast<ReferenceType const*>(&_type);
+ if (!referenceType || referenceType->location() == DataLocation::Storage)
+ {
+ for (size_t i = 0; i < _type.getSizeOnStack(); ++i)
+ m_context << u256(0);
+ if (_toMemory)
+ utils.storeInMemoryDynamic(_type);
+ return;
+ }
+ solAssert(referenceType->location() == DataLocation::Memory, "");
+ if (!_toMemory)
+ {
+ // allocate memory
+ utils.fetchFreeMemoryPointer();
+ m_context << eth::Instruction::DUP1 << u256(max(32u, _type.getCalldataEncodedSize()));
+ m_context << eth::Instruction::ADD;
+ utils.storeFreeMemoryPointer();
+ m_context << eth::Instruction::DUP1;
+ }
+
+ if (auto structType = dynamic_cast<StructType const*>(&_type))
+ for (auto const& member: structType->getMembers())
+ appendStackVariableInitialisation(*member.type, true);
+ else if (auto arrayType = dynamic_cast<ArrayType const*>(&_type))
+ {
+ if (arrayType->isDynamicallySized())
+ {
+ // zero length
+ m_context << u256(0);
+ CompilerUtils(m_context).storeInMemoryDynamic(IntegerType(256));
+ }
+ else if (arrayType->getLength() > 0)
+ {
+ m_context << arrayType->getLength() << eth::Instruction::SWAP1;
+ // stack: items_to_do memory_pos
+ auto repeat = m_context.newTag();
+ m_context << repeat;
+ appendStackVariableInitialisation(*arrayType->getBaseType(), true);
+ m_context << eth::Instruction::SWAP1 << u256(1) << eth::Instruction::SWAP1;
+ m_context << eth::Instruction::SUB << eth::Instruction::SWAP1;
+ m_context << eth::Instruction::DUP2;
+ m_context.appendConditionalJumpTo(repeat);
+ m_context << eth::Instruction::SWAP1 << eth::Instruction::POP;
+ }
+ }
+ else
+ solAssert(false, "Requested initialisation for unknown type: " + _type.toString());
+
+ if (!_toMemory)
+ // remove the updated memory pointer
+ m_context << eth::Instruction::POP;
+}
+
void ExpressionCompiler::appendStateVariableAccessor(VariableDeclaration const& _varDecl)
{
CompilerContext::LocationSetter locationSetter(m_context, _varDecl);