Skip to content

Commit 28ca802

Browse files
committed
Adapt ArrayUtils to deal with wrap-around static arrays
Also sometimes cleanup can be skipped when copying from a smaller source array into a larger target array
1 parent f67620e commit 28ca802

27 files changed

+54
-19
lines changed

libsolidity/codegen/ArrayUtils.cpp

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -290,7 +290,25 @@ void ArrayUtils::copyArrayToStorage(ArrayType const& _targetType, ArrayType cons
290290
_context << Instruction::POP << Instruction::SWAP1 << Instruction::POP;
291291
// stack: target_ref target_data_end target_data_pos_updated
292292
if (targetBaseType->storageBytes() < 32)
293+
{
294+
if (!targetType->isDynamicallySized() && !sourceType->isDynamicallySized())
295+
if (auto const* targetArrayType = dynamic_cast<ArrayType const*>(targetType))
296+
{
297+
auto const* sourceArrayType = dynamic_cast<ArrayType const*>(sourceType);
298+
solAssert(sourceArrayType);
299+
300+
auto const numSourceItemsPerSlot = 32 / sourceArrayType->baseType()->storageBytes();
301+
auto const paddedLength = numSourceItemsPerSlot * sourceArrayType->storageSize();
302+
auto const paddedTargetType = TypeProvider::array(targetArrayType->location(), targetArrayType->baseType(), paddedLength);
303+
304+
if (paddedTargetType->storageSize() >= targetArrayType->storageSize())
305+
{
306+
_context << Instruction::POP << Instruction::POP;
307+
return;
308+
}
309+
}
293310
utils.clearStorageLoop(TypeProvider::uint256(), !targetType->isDynamicallySized());
311+
}
294312
else
295313
utils.clearStorageLoop(targetBaseType, !targetType->isDynamicallySized());
296314
_context << Instruction::POP;
@@ -775,7 +793,7 @@ void ArrayUtils::clearStorageLoop(Type const* _type, bool _canOverflow) const
775793
{
776794
solAssert(_type->storageBytes() >= 32, "");
777795
m_context.callLowLevelFunction(
778-
"$clearStorageLoop_" + _type->identifier(),
796+
"$clearStorageLoop_" + _type->identifier() + (_canOverflow ? "_canOverflow" : "cannotOverflow"),
779797
2,
780798
1,
781799
[_type, _canOverflow](CompilerContext& _context)

test/libsolidity/semanticTests/abiEncoderV2/calldata_overlapped_dynamic_arrays.sol

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ contract C {
3434
// f_which(uint256[],uint256[2],uint256): 0x40, 1, 2, 1 -> FAILURE
3535
// f_storage(uint256[],uint256[2]): 0x20, 1, 2 -> 0x20, 0x60, 0x20, 1, 2
3636
// gas irOptimized: 111409
37-
// gas legacy: 112707
37+
// gas legacy: 112704
3838
// gas legacyOptimized: 111845
3939
// f_storage(uint256[],uint256[2]): 0x40, 1, 2, 5, 6 -> 0x20, 0x80, 0x20, 2, 5, 6
4040
// f_storage(uint256[],uint256[2]): 0x40, 1, 2, 5 -> FAILURE

test/libsolidity/semanticTests/abiEncoderV2/storage_array_encoding.sol

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,9 @@ contract C {
1919
// ----
2020
// h(uint256[2][]): 0x20, 3, 123, 124, 223, 224, 323, 324 -> 32, 256, 0x20, 3, 123, 124, 223, 224, 323, 324
2121
// gas irOptimized: 180080
22-
// gas legacy: 184233
22+
// gas legacy: 184224
2323
// gas legacyOptimized: 180856
2424
// i(uint256[2][2]): 123, 124, 223, 224 -> 32, 128, 123, 124, 223, 224
2525
// gas irOptimized: 112031
26-
// gas legacy: 115091
26+
// gas legacy: 115082
2727
// gas legacyOptimized: 112657

test/libsolidity/semanticTests/array/arrays_complex_from_and_to_storage.sol

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ contract Test {
1313
// ----
1414
// set(uint24[3][]): 0x20, 0x06, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12 -> 0x06
1515
// gas irOptimized: 185216
16-
// gas legacy: 211054
16+
// gas legacy: 211036
1717
// gas legacyOptimized: 206077
1818
// data(uint256,uint256): 0x02, 0x02 -> 0x09
1919
// data(uint256,uint256): 0x05, 0x01 -> 0x11

test/libsolidity/semanticTests/array/constant_var_as_array_length.sol

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ contract C {
1010
// constructor(): 1, 2, 3 ->
1111
// gas irOptimized: 124991
1212
// gas irOptimized code: 14800
13-
// gas legacy: 134317
13+
// gas legacy: 134298
1414
// gas legacy code: 46200
1515
// gas legacyOptimized: 127166
1616
// gas legacyOptimized code: 23400

test/libsolidity/semanticTests/array/copying/array_copy_calldata_storage.sol

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,6 @@ contract c {
2121
// ----
2222
// store(uint256[9],uint8[3][]): 21, 22, 23, 24, 25, 26, 27, 28, 29, 0x140, 4, 1, 2, 3, 11, 12, 13, 21, 22, 23, 31, 32, 33 -> 32
2323
// gas irOptimized: 647725
24-
// gas legacy: 694354
24+
// gas legacy: 694351
2525
// gas legacyOptimized: 693849
2626
// retrieve() -> 9, 28, 9, 28, 4, 3, 32

test/libsolidity/semanticTests/array/copying/array_copy_including_array.sol

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ contract c {
3636
// ----
3737
// test() -> 0x02000202
3838
// gas irOptimized: 4549676
39-
// gas legacy: 4473477
39+
// gas legacy: 4473198
4040
// gas legacyOptimized: 4445748
4141
// storageEmpty -> 1
4242
// clear() -> 0, 0

test/libsolidity/semanticTests/array/copying/array_copy_nested_array.sol

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,5 +13,5 @@ contract c {
1313
// ----
1414
// test(uint256[2][]): 32, 3, 7, 8, 9, 10, 11, 12 -> 10
1515
// gas irOptimized: 689552
16-
// gas legacy: 686176
16+
// gas legacy: 686086
1717
// gas legacyOptimized: 685611

test/libsolidity/semanticTests/array/copying/array_copy_storage_storage_different_base_nested.sol

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,5 +22,5 @@ contract c {
2222
// ----
2323
// test() -> 3, 4
2424
// gas irOptimized: 169602
25-
// gas legacy: 175415
25+
// gas legacy: 175289
2626
// gas legacyOptimized: 172533

test/libsolidity/semanticTests/array/copying/array_copy_storage_storage_static_static.sol

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,5 +15,5 @@ contract c {
1515
// ----
1616
// test() -> 8, 0
1717
// gas irOptimized: 196251
18-
// gas legacy: 194842
18+
// gas legacy: 194779
1919
// gas legacyOptimized: 194281

0 commit comments

Comments
 (0)