| 635 | } |
| 636 | |
| 637 | void CompilerUtils::zeroInitialiseMemoryArray(ArrayType const& _type) |
| 638 | { |
| 639 | if (_type.baseType()->hasSimpleZeroValueInMemory()) |
| 640 | { |
| 641 | solAssert(_type.baseType()->isValueType()); |
| 642 | Whiskers templ(R"({ |
| 643 | let size := mul(length, <element_size>) |
| 644 | // cheap way of zero-initializing a memory range |
| 645 | calldatacopy(memptr, calldatasize(), size) |
| 646 | memptr := add(memptr, size) |
| 647 | })"); |
| 648 | templ("element_size", std::to_string(_type.memoryStride())); |
| 649 | m_context.appendInlineAssembly(templ.render(), {"length", "memptr"}); |
| 650 | } |
| 651 | else |
| 652 | { |
| 653 | auto repeat = m_context.newTag(); |
| 654 | m_context << repeat; |
| 655 | pushZeroValue(*_type.baseType()); |
| 656 | storeInMemoryDynamic(*_type.baseType()); |
| 657 | m_context << Instruction::SWAP1 << u256(1) << Instruction::SWAP1; |
| 658 | m_context << Instruction::SUB << Instruction::SWAP1; |
| 659 | m_context << Instruction::DUP2; |
| 660 | m_context.appendConditionalJumpTo(repeat); |
| 661 | } |
| 662 | m_context << Instruction::SWAP1 << Instruction::POP; |
| 663 | } |
| 664 | |
| 665 | void CompilerUtils::memoryCopy32() |
| 666 | { |
no test coverage detected