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