diff options
author | chriseth <chris@ethereum.org> | 2017-01-25 00:37:22 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-01-25 00:37:22 +0800 |
commit | 3dc83aa34e83d668cde82953f9efa94ebb7de8ed (patch) | |
tree | 06013ebd774f99584be9ca09c22feac010ebc2c7 /libsolidity/codegen/CompilerUtils.cpp | |
parent | 29dab03ec8b595fc25e010bd8b60b2e280d0ebed (diff) | |
parent | 7e6f1b3f0008d03e6cdfa186b8f9976570865d4e (diff) | |
download | dexon-solidity-3dc83aa34e83d668cde82953f9efa94ebb7de8ed.tar dexon-solidity-3dc83aa34e83d668cde82953f9efa94ebb7de8ed.tar.gz dexon-solidity-3dc83aa34e83d668cde82953f9efa94ebb7de8ed.tar.bz2 dexon-solidity-3dc83aa34e83d668cde82953f9efa94ebb7de8ed.tar.lz dexon-solidity-3dc83aa34e83d668cde82953f9efa94ebb7de8ed.tar.xz dexon-solidity-3dc83aa34e83d668cde82953f9efa94ebb7de8ed.tar.zst dexon-solidity-3dc83aa34e83d668cde82953f9efa94ebb7de8ed.zip |
Merge pull request #1588 from ethereum/fixrecursivestructs
Introduce low-level functions
Diffstat (limited to 'libsolidity/codegen/CompilerUtils.cpp')
-rw-r--r-- | libsolidity/codegen/CompilerUtils.cpp | 67 |
1 files changed, 38 insertions, 29 deletions
diff --git a/libsolidity/codegen/CompilerUtils.cpp b/libsolidity/codegen/CompilerUtils.cpp index 7d382aba..caf3b1ac 100644 --- a/libsolidity/codegen/CompilerUtils.cpp +++ b/libsolidity/codegen/CompilerUtils.cpp @@ -820,37 +820,46 @@ void CompilerUtils::pushZeroValue(Type const& _type) } solAssert(referenceType->location() == DataLocation::Memory, ""); - m_context << u256(max(32u, _type.calldataEncodedSize())); - allocateMemory(); - m_context << Instruction::DUP1; + TypePointer type = _type.shared_from_this(); + m_context.callLowLevelFunction( + "$pushZeroValue_" + referenceType->identifier(), + 0, + 1, + [type](CompilerContext& _context) { + CompilerUtils utils(_context); + _context << u256(max(32u, type->calldataEncodedSize())); + utils.allocateMemory(); + _context << Instruction::DUP1; + + if (auto structType = dynamic_cast<StructType const*>(type.get())) + for (auto const& member: structType->members(nullptr)) + { + utils.pushZeroValue(*member.type); + utils.storeInMemoryDynamic(*member.type); + } + else if (auto arrayType = dynamic_cast<ArrayType const*>(type.get())) + { + if (arrayType->isDynamicallySized()) + { + // zero length + _context << u256(0); + utils.storeInMemoryDynamic(IntegerType(256)); + } + else if (arrayType->length() > 0) + { + _context << arrayType->length() << Instruction::SWAP1; + // stack: items_to_do memory_pos + utils.zeroInitialiseMemoryArray(*arrayType); + // stack: updated_memory_pos + } + } + else + solAssert(false, "Requested initialisation for unknown type: " + type->toString()); - if (auto structType = dynamic_cast<StructType const*>(&_type)) - for (auto const& member: structType->members(nullptr)) - { - pushZeroValue(*member.type); - storeInMemoryDynamic(*member.type); + // remove the updated memory pointer + _context << Instruction::POP; } - else if (auto arrayType = dynamic_cast<ArrayType const*>(&_type)) - { - if (arrayType->isDynamicallySized()) - { - // zero length - m_context << u256(0); - storeInMemoryDynamic(IntegerType(256)); - } - else if (arrayType->length() > 0) - { - m_context << arrayType->length() << Instruction::SWAP1; - // stack: items_to_do memory_pos - zeroInitialiseMemoryArray(*arrayType); - // stack: updated_memory_pos - } - } - else - solAssert(false, "Requested initialisation for unknown type: " + _type.toString()); - - // remove the updated memory pointer - m_context << Instruction::POP; + ); } void CompilerUtils::moveToStackVariable(VariableDeclaration const& _variable) |