Skip to content

Commit 0552458

Browse files
committed
wip
1 parent e5d1fb8 commit 0552458

File tree

4 files changed

+23
-20
lines changed

4 files changed

+23
-20
lines changed

Diff for: libsolidity/codegen/ArrayUtils.cpp

+13-12
Original file line numberDiff line numberDiff line change
@@ -290,9 +290,9 @@ 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-
utils.clearStorageLoop(TypeProvider::uint256(), false); // TODO: check the boolean
293+
utils.clearStorageLoop(TypeProvider::uint256(), !_targetType.isDynamicallySized());
294294
else
295-
utils.clearStorageLoop(targetBaseType, false); // TODO: check the boolean
295+
utils.clearStorageLoop(targetBaseType, !_targetType.isDynamicallySized());
296296
_context << Instruction::POP;
297297
}
298298
);
@@ -590,9 +590,10 @@ void ArrayUtils::clearArray(ArrayType const& _typeIn) const
590590
ArrayUtils(_context).convertLengthToSize(_type);
591591
_context << Instruction::ADD << Instruction::SWAP1;
592592
if (_type.baseType()->storageBytes() < 32)
593-
ArrayUtils(_context).clearStorageLoop(TypeProvider::uint256(), !_type.isDynamicallySized()); // TODO: check boolean
593+
// wraps around cleaning for static arrays
594+
ArrayUtils(_context).clearStorageLoop(TypeProvider::uint256(), !_type.isDynamicallySized());
594595
else
595-
ArrayUtils(_context).clearStorageLoop(_type.baseType(), !_type.isDynamicallySized()); // TODO: check boolean
596+
ArrayUtils(_context).clearStorageLoop(_type.baseType(), !_type.isDynamicallySized());
596597
_context << Instruction::POP;
597598
}
598599
solAssert(_context.stackHeight() == stackHeightStart - 2, "");
@@ -631,9 +632,9 @@ void ArrayUtils::clearDynamicArray(ArrayType const& _type) const
631632
<< Instruction::SWAP1;
632633
// stack: data_pos_end data_pos
633634
if (_type.storageStride() < 32)
634-
clearStorageLoop(TypeProvider::uint256(), false); // TODO: check boolean
635+
clearStorageLoop(TypeProvider::uint256(), /* _canOverflow */ false);
635636
else
636-
clearStorageLoop(_type.baseType(), false); // TODO: check boolean
637+
clearStorageLoop(_type.baseType(), /* _canOverflow */ false);
637638
// cleanup
638639
m_context << endTag;
639640
m_context << Instruction::POP;
@@ -738,7 +739,7 @@ void ArrayUtils::resizeDynamicArray(ArrayType const& _typeIn) const
738739
ArrayUtils(_context).convertLengthToSize(_type);
739740
_context << Instruction::DUP2 << Instruction::ADD << Instruction::SWAP1;
740741
// stack: ref new_length current_length first_word data_location_end data_location
741-
ArrayUtils(_context).clearStorageLoop(TypeProvider::uint256(), false);
742+
ArrayUtils(_context).clearStorageLoop(TypeProvider::uint256(), /* _canOverflow */ false);
742743
_context << Instruction::POP;
743744
// stack: ref new_length current_length first_word
744745
solAssert(_context.stackHeight() - stackHeightStart == 4 - 2, "3");
@@ -777,9 +778,9 @@ void ArrayUtils::resizeDynamicArray(ArrayType const& _typeIn) const
777778
_context << Instruction::SWAP2 << Instruction::ADD;
778779
// stack: ref new_length delete_end delete_start
779780
if (_type.storageStride() < 32)
780-
ArrayUtils(_context).clearStorageLoop(TypeProvider::uint256(), false);
781+
ArrayUtils(_context).clearStorageLoop(TypeProvider::uint256(), /* _canOverflow */ false);
781782
else
782-
ArrayUtils(_context).clearStorageLoop(_type.baseType(), false);
783+
ArrayUtils(_context).clearStorageLoop(_type.baseType(), /* _canOverflow */ false);
783784

784785
_context << resizeEnd;
785786
// cleanup
@@ -921,14 +922,14 @@ void ArrayUtils::popStorageArrayElement(ArrayType const& _type) const
921922
}
922923
}
923924

924-
void ArrayUtils::clearStorageLoop(Type const* _type, bool _assumeEndAfterStart) const
925+
void ArrayUtils::clearStorageLoop(Type const* _type, bool _canOverflow) const
925926
{
926927
solAssert(_type->storageBytes() >= 32, "");
927928
m_context.callLowLevelFunction(
928929
"$clearStorageLoop_" + _type->identifier(),
929930
2,
930931
1,
931-
[_type, _assumeEndAfterStart](CompilerContext& _context)
932+
[_type, _canOverflow](CompilerContext& _context)
932933
{
933934
unsigned stackHeightStart = _context.stackHeight();
934935
if (_type->category() == Type::Category::Mapping)
@@ -944,7 +945,7 @@ void ArrayUtils::clearStorageLoop(Type const* _type, bool _assumeEndAfterStart)
944945
_context <<
945946
Instruction::DUP1 <<
946947
Instruction::DUP3;
947-
if (_assumeEndAfterStart)
948+
if (_canOverflow)
948949
_context << Instruction::EQ;
949950
else
950951
_context << Instruction::GT << Instruction::ISZERO;

Diff for: libsolidity/codegen/ArrayUtils.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -77,9 +77,10 @@ class ArrayUtils
7777
/// Stack post:
7878
void popStorageArrayElement(ArrayType const& _type) const;
7979
/// Appends a loop that clears a sequence of storage slots of the given type (excluding end).
80+
/// @param _canOverflow whether the storage is treated as circular when clearing.
8081
/// Stack pre: end_ref start_ref
8182
/// Stack post: end_ref
82-
void clearStorageLoop(Type const* _type, bool _assumeEndAfterStart) const;
83+
void clearStorageLoop(Type const* _type, bool _canOverflow) const;
8384
/// Converts length to size (number of storage slots or calldata/memory bytes).
8485
/// if @a _pad then add padding to multiples of 32 bytes for calldata/memory.
8586
/// Stack pre: length

Diff for: libsolidity/codegen/YulUtilFunctions.cpp

+6-6
Original file line numberDiff line numberDiff line change
@@ -1431,7 +1431,7 @@ std::string YulUtilFunctions::cleanUpStorageArrayEndFunction(ArrayType const& _t
14311431
)")
14321432
("convertToSize", arrayConvertLengthToSize(_type))
14331433
("dataPosition", arrayDataAreaFunction(_type))
1434-
("clearStorageRange", clearStorageRangeFunction(*_type.baseType(), false))
1434+
("clearStorageRange", clearStorageRangeFunction(*_type.baseType(), !_type.isDynamicallySized()))
14351435
("packed", _type.baseType()->storageBytes() <= 16)
14361436
("itemsPerSlot", std::to_string(32 / _type.baseType()->storageBytes()))
14371437
("storageBytes", std::to_string(_type.baseType()->storageBytes()))
@@ -1483,7 +1483,7 @@ std::string YulUtilFunctions::cleanUpDynamicByteArrayEndSlotsFunction(ArrayType
14831483
)")
14841484
("dataLocation", arrayDataAreaFunction(_type))
14851485
("div32Ceil", divide32CeilFunction())
1486-
("clearStorageRange", clearStorageRangeFunction(*_type.baseType(), false))
1486+
("clearStorageRange", clearStorageRangeFunction(*_type.baseType(), /* _canOverflow */ false))
14871487
.render();
14881488
});
14891489
}
@@ -1523,7 +1523,7 @@ std::string YulUtilFunctions::decreaseByteArraySizeFunction(ArrayType const& _ty
15231523
("functionName", functionName)
15241524
("dataPosition", arrayDataAreaFunction(_type))
15251525
("partialClearStorageSlot", partialClearStorageSlotFunction())
1526-
("clearStorageRange", clearStorageRangeFunction(*_type.baseType(), true))
1526+
("clearStorageRange", clearStorageRangeFunction(*_type.baseType(), /* _canOverflow */ true))
15271527
("transitLongToShort", byteArrayTransitLongToShortFunction(_type))
15281528
("div32Ceil", divide32CeilFunction())
15291529
("encodeUsedSetLen", shortByteArrayEncodeUsedAreaSetLengthFunction())
@@ -1817,7 +1817,7 @@ std::string YulUtilFunctions::partialClearStorageSlotFunction()
18171817
});
18181818
}
18191819

1820-
std::string YulUtilFunctions::clearStorageRangeFunction(Type const& _type, bool _assumeEndAfterStart)
1820+
std::string YulUtilFunctions::clearStorageRangeFunction(Type const& _type, bool _canOverflow)
18211821
{
18221822
if (_type.storageBytes() < 32)
18231823
solAssert(_type.isValueType(), "");
@@ -1834,7 +1834,7 @@ std::string YulUtilFunctions::clearStorageRangeFunction(Type const& _type, bool
18341834
}
18351835
)")
18361836
("functionName", functionName)
1837-
("compare", _assumeEndAfterStart ? "sub" : "lt")
1837+
("compare", _canOverflow ? "sub" : "lt")
18381838
("setToZero", storageSetToZeroFunction(_type.storageBytes() < 32 ? *TypeProvider::uint256() : _type, VariableDeclaration::Location::Unspecified))
18391839
("increment", _type.storageSize().str())
18401840
.render();
@@ -1872,7 +1872,7 @@ std::string YulUtilFunctions::clearStorageArrayFunction(ArrayType const& _type)
18721872
(
18731873
"clearRange",
18741874
_type.baseType()->category() != Type::Category::Mapping ?
1875-
clearStorageRangeFunction((_type.baseType()->storageBytes() < 32) ? *TypeProvider::uint256() : *_type.baseType(), true) :
1875+
clearStorageRangeFunction((_type.baseType()->storageBytes() < 32) ? *TypeProvider::uint256() : *_type.baseType(), /* _canOverflow */ true) :
18761876
""
18771877
)
18781878
("lenToSize", arrayConvertLengthToSize(_type))

Diff for: libsolidity/codegen/YulUtilFunctions.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -268,7 +268,8 @@ class YulUtilFunctions
268268
/// @returns the name of a function that will clear the storage area given
269269
/// by the start and end (exclusive) parameters (slots).
270270
/// signature: (start, end)
271-
std::string clearStorageRangeFunction(Type const& _type, bool _assumeEndAfterStart);
271+
/// if _canOverflow is true, it treats the storage as circular and clears by wrapping around.
272+
std::string clearStorageRangeFunction(Type const& _type, bool _canOverflow);
272273

273274
/// @returns the name of a function that will clear the given storage array
274275
/// signature: (slot) ->

0 commit comments

Comments
 (0)