mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Add stride helpers to ArrayType.
This commit is contained in:
parent
f003696d7e
commit
32190dac48
@ -736,6 +736,13 @@ public:
|
||||
|
||||
TypePointer copyForLocation(DataLocation _location, bool _isPointer) const override;
|
||||
|
||||
/// The offset to advance in calldata to move from one array element to the next.
|
||||
unsigned calldataStride() const { return isByteArray() ? 1 : m_baseType->calldataEncodedSize(); }
|
||||
/// The offset to advance in memory to move from one array element to the next.
|
||||
unsigned memoryStride() const { return isByteArray() ? 1 : m_baseType->memoryHeadSize(); }
|
||||
/// The offset to advance in storage to move from one array element to the next.
|
||||
unsigned storageStride() const { return isByteArray() ? 1 : m_baseType->storageBytes(); }
|
||||
|
||||
private:
|
||||
/// String is interpreted as a subtype of Bytes.
|
||||
enum class ArrayKind { Ordinary, Bytes, String };
|
||||
|
@ -623,7 +623,7 @@ void ArrayUtils::clearDynamicArray(ArrayType const& _type) const
|
||||
m_context << Instruction::SWAP1 << Instruction::DUP2 << Instruction::ADD
|
||||
<< Instruction::SWAP1;
|
||||
// stack: data_pos_end data_pos
|
||||
if (_type.isByteArray() || _type.baseType()->storageBytes() < 32)
|
||||
if (_type.storageStride() < 32)
|
||||
clearStorageLoop(make_shared<IntegerType>(256));
|
||||
else
|
||||
clearStorageLoop(_type.baseType());
|
||||
@ -769,7 +769,7 @@ void ArrayUtils::resizeDynamicArray(ArrayType const& _typeIn) const
|
||||
// stack: ref new_length data_pos new_size delete_end
|
||||
_context << Instruction::SWAP2 << Instruction::ADD;
|
||||
// stack: ref new_length delete_end delete_start
|
||||
if (_type.isByteArray() || _type.baseType()->storageBytes() < 32)
|
||||
if (_type.storageStride() < 32)
|
||||
ArrayUtils(_context).clearStorageLoop(make_shared<IntegerType>(256));
|
||||
else
|
||||
ArrayUtils(_context).clearStorageLoop(_type.baseType());
|
||||
|
@ -243,7 +243,7 @@ void CompilerUtils::abiDecode(TypePointers const& _typeParameters, bool _fromMem
|
||||
gt(add(array_data_start, mul(array_length, <item_size>)), input_end)
|
||||
) { revert(0, 0) }
|
||||
})");
|
||||
templ("item_size", to_string(arrayType.isByteArray() ? 1 : arrayType.baseType()->calldataEncodedSize(true)));
|
||||
templ("item_size", to_string(arrayType.calldataStride()));
|
||||
m_context.appendInlineAssembly(templ.render(), {"input_end", "base_offset", "offset", "ptr"});
|
||||
// stack: v1 v2 ... v(k-1) input_end base_offset current_offset v(k)
|
||||
moveIntoStack(3);
|
||||
@ -279,11 +279,10 @@ void CompilerUtils::abiDecode(TypePointers const& _typeParameters, bool _fromMem
|
||||
// stack: input_end base_offset next_pointer array_length data_pointer
|
||||
m_context << Instruction::SWAP2;
|
||||
// stack: input_end base_offset data_pointer array_length next_pointer
|
||||
unsigned itemSize = arrayType.isByteArray() ? 1 : arrayType.baseType()->calldataEncodedSize(true);
|
||||
m_context.appendInlineAssembly(R"({
|
||||
if or(
|
||||
gt(array_length, 0x100000000),
|
||||
gt(add(data_ptr, mul(array_length, )" + to_string(itemSize) + R"()), input_end)
|
||||
gt(add(data_ptr, mul(array_length, )" + to_string(arrayType.calldataStride()) + R"()), input_end)
|
||||
) { revert(0, 0) }
|
||||
})", {"input_end", "base_offset", "data_ptr", "array_length", "next_ptr"});
|
||||
}
|
||||
@ -517,7 +516,7 @@ void CompilerUtils::zeroInitialiseMemoryArray(ArrayType const& _type)
|
||||
codecopy(memptr, codesize(), size)
|
||||
memptr := add(memptr, size)
|
||||
})");
|
||||
templ("element_size", to_string(_type.isByteArray() ? 1 : _type.baseType()->memoryHeadSize()));
|
||||
templ("element_size", to_string(_type.memoryStride()));
|
||||
m_context.appendInlineAssembly(templ.render(), {"length", "memptr"});
|
||||
}
|
||||
else
|
||||
|
Loading…
Reference in New Issue
Block a user