mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Merge pull request #6002 from ethereum/arrayTypeStride
Add stride helpers to ArrayType.
This commit is contained in:
commit
690edc8bc9
@ -736,6 +736,13 @@ public:
|
|||||||
|
|
||||||
TypePointer copyForLocation(DataLocation _location, bool _isPointer) const override;
|
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:
|
private:
|
||||||
/// String is interpreted as a subtype of Bytes.
|
/// String is interpreted as a subtype of Bytes.
|
||||||
enum class ArrayKind { Ordinary, Bytes, String };
|
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
|
m_context << Instruction::SWAP1 << Instruction::DUP2 << Instruction::ADD
|
||||||
<< Instruction::SWAP1;
|
<< Instruction::SWAP1;
|
||||||
// stack: data_pos_end data_pos
|
// stack: data_pos_end data_pos
|
||||||
if (_type.isByteArray() || _type.baseType()->storageBytes() < 32)
|
if (_type.storageStride() < 32)
|
||||||
clearStorageLoop(make_shared<IntegerType>(256));
|
clearStorageLoop(make_shared<IntegerType>(256));
|
||||||
else
|
else
|
||||||
clearStorageLoop(_type.baseType());
|
clearStorageLoop(_type.baseType());
|
||||||
@ -769,7 +769,7 @@ void ArrayUtils::resizeDynamicArray(ArrayType const& _typeIn) const
|
|||||||
// stack: ref new_length data_pos new_size delete_end
|
// stack: ref new_length data_pos new_size delete_end
|
||||||
_context << Instruction::SWAP2 << Instruction::ADD;
|
_context << Instruction::SWAP2 << Instruction::ADD;
|
||||||
// stack: ref new_length delete_end delete_start
|
// 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));
|
ArrayUtils(_context).clearStorageLoop(make_shared<IntegerType>(256));
|
||||||
else
|
else
|
||||||
ArrayUtils(_context).clearStorageLoop(_type.baseType());
|
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)
|
gt(add(array_data_start, mul(array_length, <item_size>)), input_end)
|
||||||
) { revert(0, 0) }
|
) { 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"});
|
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)
|
// stack: v1 v2 ... v(k-1) input_end base_offset current_offset v(k)
|
||||||
moveIntoStack(3);
|
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
|
// stack: input_end base_offset next_pointer array_length data_pointer
|
||||||
m_context << Instruction::SWAP2;
|
m_context << Instruction::SWAP2;
|
||||||
// stack: input_end base_offset data_pointer array_length next_pointer
|
// stack: input_end base_offset data_pointer array_length next_pointer
|
||||||
unsigned itemSize = arrayType.isByteArray() ? 1 : arrayType.baseType()->calldataEncodedSize(true);
|
|
||||||
m_context.appendInlineAssembly(R"({
|
m_context.appendInlineAssembly(R"({
|
||||||
if or(
|
if or(
|
||||||
gt(array_length, 0x100000000),
|
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) }
|
) { revert(0, 0) }
|
||||||
})", {"input_end", "base_offset", "data_ptr", "array_length", "next_ptr"});
|
})", {"input_end", "base_offset", "data_ptr", "array_length", "next_ptr"});
|
||||||
}
|
}
|
||||||
@ -517,7 +516,7 @@ void CompilerUtils::zeroInitialiseMemoryArray(ArrayType const& _type)
|
|||||||
codecopy(memptr, codesize(), size)
|
codecopy(memptr, codesize(), size)
|
||||||
memptr := add(memptr, 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"});
|
m_context.appendInlineAssembly(templ.render(), {"length", "memptr"});
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
Loading…
Reference in New Issue
Block a user