@@ -639,156 +639,6 @@ void ArrayUtils::clearDynamicArray(ArrayType const& _type) const
639
639
m_context << Instruction::POP;
640
640
}
641
641
642
- void ArrayUtils::resizeDynamicArray (ArrayType const & _typeIn) const
643
- {
644
- Type const * type = &_typeIn;
645
- m_context.callLowLevelFunction (
646
- " $resizeDynamicArray_" + _typeIn.identifier (),
647
- 2 ,
648
- 0 ,
649
- [type](CompilerContext& _context)
650
- {
651
- ArrayType const & _type = dynamic_cast <ArrayType const &>(*type);
652
- solAssert (_type.location () == DataLocation::Storage, " " );
653
- solAssert (_type.isDynamicallySized (), " " );
654
- if (!_type.isByteArrayOrString () && _type.baseType ()->storageBytes () < 32 )
655
- solAssert (_type.baseType ()->isValueType (), " Invalid storage size for non-value type." );
656
-
657
- unsigned stackHeightStart = _context.stackHeight ();
658
- evmasm::AssemblyItem resizeEnd = _context.newTag ();
659
-
660
- // stack: ref new_length
661
- // fetch old length
662
- ArrayUtils (_context).retrieveLength (_type, 1 );
663
- // stack: ref new_length old_length
664
- solAssert (_context.stackHeight () - stackHeightStart == 3 - 2 , " 2" );
665
-
666
- // Special case for short byte arrays, they are stored together with their length
667
- if (_type.isByteArrayOrString ())
668
- {
669
- evmasm::AssemblyItem regularPath = _context.newTag ();
670
- // We start by a large case-distinction about the old and new length of the byte array.
671
-
672
- _context << Instruction::DUP3 << Instruction::SLOAD;
673
- // stack: ref new_length current_length ref_value
674
-
675
- solAssert (_context.stackHeight () - stackHeightStart == 4 - 2 , " 3" );
676
- _context << Instruction::DUP2 << u256 (31 ) << Instruction::LT;
677
- evmasm::AssemblyItem currentIsLong = _context.appendConditionalJump ();
678
- _context << Instruction::DUP3 << u256 (31 ) << Instruction::LT;
679
- evmasm::AssemblyItem newIsLong = _context.appendConditionalJump ();
680
-
681
- // Here: short -> short
682
-
683
- // Compute 1 << (256 - 8 * new_size)
684
- evmasm::AssemblyItem shortToShort = _context.newTag ();
685
- _context << shortToShort;
686
- _context << Instruction::DUP3 << u256 (8 ) << Instruction::MUL;
687
- _context << u256 (0x100 ) << Instruction::SUB;
688
- _context << u256 (2 ) << Instruction::EXP;
689
- // Divide and multiply by that value, clearing bits.
690
- _context << Instruction::DUP1 << Instruction::SWAP2;
691
- _context << Instruction::DIV << Instruction::MUL;
692
- // Insert 2*length.
693
- _context << Instruction::DUP3 << Instruction::DUP1 << Instruction::ADD;
694
- _context << Instruction::OR;
695
- // Store.
696
- _context << Instruction::DUP4 << Instruction::SSTORE;
697
- solAssert (_context.stackHeight () - stackHeightStart == 3 - 2 , " 3" );
698
- _context.appendJumpTo (resizeEnd);
699
-
700
- _context.adjustStackOffset (1 ); // we have to do that because of the jumps
701
- // Here: short -> long
702
-
703
- _context << newIsLong;
704
- // stack: ref new_length current_length ref_value
705
- solAssert (_context.stackHeight () - stackHeightStart == 4 - 2 , " 3" );
706
- // Zero out lower-order byte.
707
- _context << u256 (0xff ) << Instruction::NOT << Instruction::AND;
708
- // Store at data location.
709
- _context << Instruction::DUP4;
710
- CompilerUtils (_context).computeHashStatic ();
711
- _context << Instruction::SSTORE;
712
- // stack: ref new_length current_length
713
- // Store new length: Compute 2*length + 1 and store it.
714
- _context << Instruction::DUP2 << Instruction::DUP1 << Instruction::ADD;
715
- _context << u256 (1 ) << Instruction::ADD;
716
- // stack: ref new_length current_length 2*new_length+1
717
- _context << Instruction::DUP4 << Instruction::SSTORE;
718
- solAssert (_context.stackHeight () - stackHeightStart == 3 - 2 , " 3" );
719
- _context.appendJumpTo (resizeEnd);
720
-
721
- _context.adjustStackOffset (1 ); // we have to do that because of the jumps
722
-
723
- _context << currentIsLong;
724
- _context << Instruction::DUP3 << u256 (31 ) << Instruction::LT;
725
- _context.appendConditionalJumpTo (regularPath);
726
-
727
- // Here: long -> short
728
- // Read the first word of the data and store it on the stack. Clear the data location and
729
- // then jump to the short -> short case.
730
-
731
- // stack: ref new_length current_length ref_value
732
- solAssert (_context.stackHeight () - stackHeightStart == 4 - 2 , " 3" );
733
- _context << Instruction::POP << Instruction::DUP3;
734
- CompilerUtils (_context).computeHashStatic ();
735
- _context << Instruction::DUP1 << Instruction::SLOAD << Instruction::SWAP1;
736
- // stack: ref new_length current_length first_word data_location
737
- _context << Instruction::DUP3;
738
- ArrayUtils (_context).convertLengthToSize (_type);
739
- _context << Instruction::DUP2 << Instruction::ADD << Instruction::SWAP1;
740
- // stack: ref new_length current_length first_word data_location_end data_location
741
- ArrayUtils (_context).clearStorageLoop (TypeProvider::uint256 (), false );
742
- _context << Instruction::POP;
743
- // stack: ref new_length current_length first_word
744
- solAssert (_context.stackHeight () - stackHeightStart == 4 - 2 , " 3" );
745
- _context.appendJumpTo (shortToShort);
746
-
747
- _context << regularPath;
748
- // stack: ref new_length current_length ref_value
749
- _context << Instruction::POP;
750
- }
751
-
752
- // Change of length for a regular array (i.e. length at location, data at KECCAK256(location)).
753
- // stack: ref new_length old_length
754
- // store new length
755
- _context << Instruction::DUP2;
756
- if (_type.isByteArrayOrString ())
757
- // For a "long" byte array, store length as 2*length+1
758
- _context << Instruction::DUP1 << Instruction::ADD << u256 (1 ) << Instruction::ADD;
759
- _context << Instruction::DUP4 << Instruction::SSTORE;
760
- // skip if size is not reduced
761
- _context << Instruction::DUP2 << Instruction::DUP2
762
- << Instruction::GT << Instruction::ISZERO;
763
- _context.appendConditionalJumpTo (resizeEnd);
764
-
765
- // size reduced, clear the end of the array
766
- // stack: ref new_length old_length
767
- ArrayUtils (_context).convertLengthToSize (_type);
768
- _context << Instruction::DUP2;
769
- ArrayUtils (_context).convertLengthToSize (_type);
770
- // stack: ref new_length old_size new_size
771
- // compute data positions
772
- _context << Instruction::DUP4;
773
- CompilerUtils (_context).computeHashStatic ();
774
- // stack: ref new_length old_size new_size data_pos
775
- _context << Instruction::SWAP2 << Instruction::DUP3 << Instruction::ADD;
776
- // stack: ref new_length data_pos new_size delete_end
777
- _context << Instruction::SWAP2 << Instruction::ADD;
778
- // stack: ref new_length delete_end delete_start
779
- if (_type.storageStride () < 32 )
780
- ArrayUtils (_context).clearStorageLoop (TypeProvider::uint256 (), false );
781
- else
782
- ArrayUtils (_context).clearStorageLoop (_type.baseType (), false );
783
-
784
- _context << resizeEnd;
785
- // cleanup
786
- _context << Instruction::POP << Instruction::POP << Instruction::POP;
787
- solAssert (_context.stackHeight () == stackHeightStart - 2 , " " );
788
- }
789
- );
790
- }
791
-
792
642
void ArrayUtils::incrementDynamicArraySize (ArrayType const & _type) const
793
643
{
794
644
solAssert (_type.location () == DataLocation::Storage, " " );
0 commit comments