mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Merge pull request #9121 from ethereum/solYulIndexAccess
[SolYul] Index access to fixed bytes and byte arrays.
This commit is contained in:
commit
1319396bfb
@ -1730,7 +1730,7 @@ void IRGeneratorForStatements::endVisit(IndexAccess const& _indexAccess)
|
||||
|
||||
setLValue(_indexAccess, IRLValue{
|
||||
*arrayType.baseType(),
|
||||
IRLValue::Memory{memAddress}
|
||||
IRLValue::Memory{memAddress, arrayType.isByteArray()}
|
||||
});
|
||||
break;
|
||||
}
|
||||
@ -1763,7 +1763,23 @@ void IRGeneratorForStatements::endVisit(IndexAccess const& _indexAccess)
|
||||
}
|
||||
}
|
||||
else if (baseType.category() == Type::Category::FixedBytes)
|
||||
solUnimplementedAssert(false, "");
|
||||
{
|
||||
auto const& fixedBytesType = dynamic_cast<FixedBytesType const&>(baseType);
|
||||
solAssert(_indexAccess.indexExpression(), "Index expression expected.");
|
||||
|
||||
IRVariable index{m_context.newYulVariable(), *TypeProvider::uint256()};
|
||||
define(index, *_indexAccess.indexExpression());
|
||||
m_code << Whiskers(R"(
|
||||
if iszero(lt(<index>, <length>)) { invalid() }
|
||||
let <result> := <shl248>(byte(<index>, <array>))
|
||||
)")
|
||||
("index", index.name())
|
||||
("length", to_string(fixedBytesType.numBytes()))
|
||||
("array", IRVariable(_indexAccess.baseExpression()).name())
|
||||
("shl248", m_utils.shiftLeftFunction(256 - 8))
|
||||
("result", IRVariable(_indexAccess).name())
|
||||
.render();
|
||||
}
|
||||
else if (baseType.category() == Type::Category::TypeType)
|
||||
{
|
||||
solAssert(baseType.sizeOnStack() == 0, "");
|
||||
|
20
test/libsolidity/semanticTests/array/index_access.sol
Normal file
20
test/libsolidity/semanticTests/array/index_access.sol
Normal file
@ -0,0 +1,20 @@
|
||||
contract C {
|
||||
function to_little_endian_64(uint64 value) public pure returns (bytes memory ret) {
|
||||
ret = new bytes(8);
|
||||
bytes8 bytesValue = bytes8(value);
|
||||
// Byteswapping during copying to bytes.
|
||||
ret[0] = bytesValue[7];
|
||||
ret[1] = bytesValue[6];
|
||||
ret[2] = bytesValue[5];
|
||||
ret[3] = bytesValue[4];
|
||||
ret[4] = bytesValue[3];
|
||||
ret[5] = bytesValue[2];
|
||||
ret[6] = bytesValue[1];
|
||||
ret[7] = bytesValue[0];
|
||||
}
|
||||
}
|
||||
// ====
|
||||
// compileViaYul: also
|
||||
// ----
|
||||
// to_little_endian_64(uint64): 0 -> 0x20, 8, 0x00
|
||||
// to_little_endian_64(uint64): 0x0102030405060708 -> 0x20, 8, 0x0807060504030201000000000000000000000000000000000000000000000000
|
Loading…
Reference in New Issue
Block a user