mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Fix copying byte arrays from storage to storage.
This commit is contained in:
parent
d84415cb3b
commit
7764ee8d86
@ -1633,8 +1633,9 @@ string YulUtilFunctions::copyByteArrayToStorageFunction(ArrayType const& _fromTy
|
||||
|
||||
let oldLen := <byteArrayLength>(sload(slot))
|
||||
|
||||
let srcOffset := 0
|
||||
<?fromMemory>
|
||||
src := add(src, 0x20)
|
||||
srcOffset := 0x20
|
||||
</fromMemory>
|
||||
|
||||
// This is not needed in all branches.
|
||||
@ -1652,14 +1653,16 @@ string YulUtilFunctions::copyByteArrayToStorageFunction(ArrayType const& _fromTy
|
||||
switch gt(newLen, 31)
|
||||
case 1 {
|
||||
let loopEnd := and(newLen, not(0x1f))
|
||||
<?fromStorage> src := <srcDataLocation>(src) </fromStorage>
|
||||
let dstPtr := dstDataArea
|
||||
let i := 0
|
||||
for { } lt(i, loopEnd) { i := add(i, 32) } {
|
||||
sstore(dstPtr, <read>(add(src, i)))
|
||||
for { } lt(i, loopEnd) { i := add(i, 0x20) } {
|
||||
sstore(dstPtr, <read>(add(src, srcOffset)))
|
||||
dstPtr := add(dstPtr, 1)
|
||||
srcOffset := add(srcOffset, <srcIncrement>)
|
||||
}
|
||||
if lt(loopEnd, newLen) {
|
||||
let lastValue := <read>(add(src, i))
|
||||
let lastValue := <read>(add(src, srcOffset))
|
||||
sstore(dstPtr, <maskBytes>(lastValue, and(newLen, 0x1f)))
|
||||
}
|
||||
sstore(slot, add(mul(newLen, 2), 1))
|
||||
@ -1667,7 +1670,7 @@ string YulUtilFunctions::copyByteArrayToStorageFunction(ArrayType const& _fromTy
|
||||
default {
|
||||
let value := 0
|
||||
if newLen {
|
||||
value := <read>(src)
|
||||
value := <read>(add(src, srcOffset))
|
||||
}
|
||||
sstore(slot, <byteArrayCombineShort>(value, newLen))
|
||||
}
|
||||
@ -1683,7 +1686,10 @@ string YulUtilFunctions::copyByteArrayToStorageFunction(ArrayType const& _fromTy
|
||||
templ("panic", panicFunction());
|
||||
templ("byteArrayLength", extractByteArrayLengthFunction());
|
||||
templ("dstDataLocation", arrayDataAreaFunction(_toType));
|
||||
if (fromStorage)
|
||||
templ("srcDataLocation", arrayDataAreaFunction(_fromType));
|
||||
templ("clearStorageRange", clearStorageRangeFunction(*_toType.baseType()));
|
||||
templ("srcIncrement", to_string(fromStorage ? 1 : 0x20));
|
||||
templ("read", fromStorage ? "sload" : fromCalldata ? "calldataload" : "mload");
|
||||
templ("maskBytes", maskBytesFunctionDynamic());
|
||||
templ("byteArrayCombineShort", shortByteArrayEncodeUsedAreaSetLengthFunction());
|
||||
|
@ -0,0 +1,26 @@
|
||||
contract c {
|
||||
bytes a;
|
||||
bytes b;
|
||||
function f(uint len) public returns (bytes memory) {
|
||||
bytes memory x = new bytes(len);
|
||||
for (uint i = 0; i < len; i++)
|
||||
x[i] = byte(uint8(i));
|
||||
a = x;
|
||||
for (uint i = 0; i < len; i++)
|
||||
assert(a[i] == x[i]);
|
||||
b = a;
|
||||
for (uint i = 0; i < len; i++)
|
||||
assert(b[i] == x[i]);
|
||||
return b;
|
||||
}
|
||||
}
|
||||
// ====
|
||||
// compileViaYul: also
|
||||
// ----
|
||||
// f(uint256): 0 -> 0x20, 0x00
|
||||
// f(uint256): 31 -> 0x20, 0x1f, 0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e00
|
||||
// f(uint256): 32 -> 0x20, 0x20, 1780731860627700044960722568376592200742329637303199754547598369979440671
|
||||
// f(uint256): 33 -> 0x20, 33, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x2000000000000000000000000000000000000000000000000000000000000000
|
||||
// f(uint256): 63 -> 0x20, 0x3f, 1780731860627700044960722568376592200742329637303199754547598369979440671, 14532552714582660066924456880521368950258152170031413196862950297402215316992
|
||||
// f(uint256): 12 -> 0x20, 0x0c, 0x0102030405060708090a0b0000000000000000000000000000000000000000
|
||||
// f(uint256): 129 -> 0x20, 0x81, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f, 29063324697304692433803953038474361308315562010425523193971352996434451193439, 0x606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f, -57896044618658097711785492504343953926634992332820282019728792003956564819968
|
Loading…
Reference in New Issue
Block a user