mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Move code that access calldata array element to separate function
This commit is contained in:
parent
492f945973
commit
ae273ff3bd
@ -1131,6 +1131,50 @@ void ArrayUtils::accessIndex(ArrayType const& _arrayType, bool _doBoundsCheck, b
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ArrayUtils::accessCallDataArrayElement(ArrayType const& _arrayType, bool _doBoundsCheck) const
|
||||||
|
{
|
||||||
|
solAssert(_arrayType.location() == DataLocation::CallData, "");
|
||||||
|
if (_arrayType.baseType()->isDynamicallyEncoded())
|
||||||
|
{
|
||||||
|
// stack layout: <base_ref> <length> <index>
|
||||||
|
ArrayUtils(m_context).accessIndex(_arrayType, _doBoundsCheck, true);
|
||||||
|
// stack layout: <base_ref> <ptr_to_tail>
|
||||||
|
|
||||||
|
CompilerUtils(m_context).accessCalldataTail(*_arrayType.baseType());
|
||||||
|
// stack layout: <tail_ref> [length]
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ArrayUtils(m_context).accessIndex(_arrayType, _doBoundsCheck);
|
||||||
|
if (_arrayType.baseType()->isValueType())
|
||||||
|
{
|
||||||
|
solAssert(_arrayType.baseType()->storageBytes() <= 32, "");
|
||||||
|
if (
|
||||||
|
!_arrayType.isByteArray() &&
|
||||||
|
_arrayType.baseType()->storageBytes() < 32 &&
|
||||||
|
m_context.experimentalFeatureActive(ExperimentalFeature::ABIEncoderV2)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
m_context << u256(32);
|
||||||
|
CompilerUtils(m_context).abiDecodeV2({_arrayType.baseType()}, false);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
CompilerUtils(m_context).loadFromMemoryDynamic(
|
||||||
|
*_arrayType.baseType(),
|
||||||
|
true,
|
||||||
|
!_arrayType.isByteArray(),
|
||||||
|
false
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
solAssert(
|
||||||
|
_arrayType.baseType()->category() == Type::Category::Struct ||
|
||||||
|
_arrayType.baseType()->category() == Type::Category::Array,
|
||||||
|
"Invalid statically sized non-value base type on array access."
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void ArrayUtils::incrementByteOffset(unsigned _byteSize, unsigned _byteOffsetPosition, unsigned _storageOffsetPosition) const
|
void ArrayUtils::incrementByteOffset(unsigned _byteSize, unsigned _byteOffsetPosition, unsigned _storageOffsetPosition) const
|
||||||
{
|
{
|
||||||
solAssert(_byteSize < 32, "");
|
solAssert(_byteSize < 32, "");
|
||||||
|
@ -104,6 +104,10 @@ public:
|
|||||||
/// Stack post (storage): [reference] storage_slot byte_offset
|
/// Stack post (storage): [reference] storage_slot byte_offset
|
||||||
/// Stack post: [reference] memory/calldata_offset
|
/// Stack post: [reference] memory/calldata_offset
|
||||||
void accessIndex(ArrayType const& _arrayType, bool _doBoundsCheck = true, bool _keepReference = false) const;
|
void accessIndex(ArrayType const& _arrayType, bool _doBoundsCheck = true, bool _keepReference = false) const;
|
||||||
|
/// Access calldata array's element and put it on stack.
|
||||||
|
/// Stack pre: reference [length] index
|
||||||
|
/// Stack post: value
|
||||||
|
void accessCallDataArrayElement(ArrayType const& _arrayType, bool _doBoundsCheck = true) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/// Adds the given number of bytes to a storage byte offset counter and also increments
|
/// Adds the given number of bytes to a storage byte offset counter and also increments
|
||||||
|
@ -1588,45 +1588,7 @@ bool ExpressionCompiler::visit(IndexAccess const& _indexAccess)
|
|||||||
setLValue<MemoryItem>(_indexAccess, *_indexAccess.annotation().type, !arrayType.isByteArray());
|
setLValue<MemoryItem>(_indexAccess, *_indexAccess.annotation().type, !arrayType.isByteArray());
|
||||||
break;
|
break;
|
||||||
case DataLocation::CallData:
|
case DataLocation::CallData:
|
||||||
if (arrayType.baseType()->isDynamicallyEncoded())
|
ArrayUtils(m_context).accessCallDataArrayElement(arrayType);
|
||||||
{
|
|
||||||
// stack layout: <base_ref> <length> <index>
|
|
||||||
ArrayUtils(m_context).accessIndex(arrayType, true, true);
|
|
||||||
// stack layout: <base_ref> <ptr_to_tail>
|
|
||||||
|
|
||||||
CompilerUtils(m_context).accessCalldataTail(*arrayType.baseType());
|
|
||||||
// stack layout: <tail_ref> [length]
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ArrayUtils(m_context).accessIndex(arrayType, true);
|
|
||||||
if (arrayType.baseType()->isValueType())
|
|
||||||
{
|
|
||||||
solAssert(arrayType.baseType()->storageBytes() <= 32, "");
|
|
||||||
if (
|
|
||||||
!arrayType.isByteArray() &&
|
|
||||||
arrayType.baseType()->storageBytes() < 32 &&
|
|
||||||
m_context.experimentalFeatureActive(ExperimentalFeature::ABIEncoderV2)
|
|
||||||
)
|
|
||||||
{
|
|
||||||
m_context << u256(32);
|
|
||||||
CompilerUtils(m_context).abiDecodeV2({arrayType.baseType()}, false);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
CompilerUtils(m_context).loadFromMemoryDynamic(
|
|
||||||
*arrayType.baseType(),
|
|
||||||
true,
|
|
||||||
!arrayType.isByteArray(),
|
|
||||||
false
|
|
||||||
);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
solAssert(
|
|
||||||
arrayType.baseType()->category() == Type::Category::Struct ||
|
|
||||||
arrayType.baseType()->category() == Type::Category::Array,
|
|
||||||
"Invalid statically sized non-value base type on array access."
|
|
||||||
);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user